@zag-js/remove-scroll 0.0.0-dev-20220604123458

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,22 @@
1
+ # @zag-js/remove-scroll
2
+
3
+
4
+
5
+ ## Installation
6
+
7
+ ```sh
8
+ yarn add @zag-js/remove-scroll
9
+ # or
10
+ npm i @zag-js/remove-scroll
11
+ ```
12
+
13
+ ## Contribution
14
+
15
+ Yes please! See the
16
+ [contributing guidelines](https://github.com/chakra-ui/zag/blob/main/CONTRIBUTING.md)
17
+ for details.
18
+
19
+ ## Licence
20
+
21
+ This project is licensed under the terms of the
22
+ [MIT license](https://github.com/chakra-ui/zag/blob/main/LICENSE).
@@ -0,0 +1,7 @@
1
+ interface BodyScrollOptions {
2
+ disabled?: boolean;
3
+ document?: Document;
4
+ }
5
+ export declare function preventBodyScroll(options?: BodyScrollOptions): () => void;
6
+ export {};
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAiCA,UAAU,iBAAiB;IACzB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,QAAQ,CAAC,EAAE,QAAQ,CAAA;CACpB;AAED,wBAAgB,iBAAiB,CAAC,OAAO,GAAE,iBAAsB,cAqDhE"}
package/dist/index.js ADDED
@@ -0,0 +1,113 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __export = (target, all) => {
6
+ for (var name in all)
7
+ __defProp(target, name, { get: all[name], enumerable: true });
8
+ };
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") {
11
+ for (let key of __getOwnPropNames(from))
12
+ if (!__hasOwnProp.call(to, key) && key !== except)
13
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
+ }
15
+ return to;
16
+ };
17
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
18
+
19
+ // src/index.ts
20
+ var src_exports = {};
21
+ __export(src_exports, {
22
+ preventBodyScroll: () => preventBodyScroll
23
+ });
24
+ module.exports = __toCommonJS(src_exports);
25
+
26
+ // ../core/dist/index.mjs
27
+ var isDom = () => typeof window !== "undefined";
28
+ function getPlatform() {
29
+ var _a;
30
+ const agent = navigator.userAgentData;
31
+ return (_a = agent == null ? void 0 : agent.platform) != null ? _a : navigator.platform;
32
+ }
33
+ var pt = (v) => isDom() && v.test(getPlatform());
34
+ var isTouchDevice = isDom() && !!navigator.maxTouchPoints;
35
+ var isMac = () => pt(/^Mac/) && !isTouchDevice;
36
+ var isApple = () => pt(/mac|iphone|ipad|ipod/i);
37
+ var isIos = () => isApple() && !isMac();
38
+
39
+ // src/index.ts
40
+ var identifier = "data-scroll-lock";
41
+ function assignStyle(el, style) {
42
+ if (!el)
43
+ return () => {
44
+ };
45
+ const previousStyle = el.style.cssText;
46
+ Object.assign(el.style, style);
47
+ return () => {
48
+ el.style.cssText = previousStyle;
49
+ };
50
+ }
51
+ function setCSSProperty(el, property, value) {
52
+ if (!el)
53
+ return () => {
54
+ };
55
+ const previousValue = el.style.getPropertyValue(property);
56
+ el.style.setProperty(property, value);
57
+ return () => {
58
+ if (previousValue) {
59
+ el.style.setProperty(property, previousValue);
60
+ } else {
61
+ el.style.removeProperty(property);
62
+ }
63
+ };
64
+ }
65
+ function getPaddingProperty(documentElement) {
66
+ const documentLeft = documentElement.getBoundingClientRect().left;
67
+ const scrollbarX = Math.round(documentLeft) + documentElement.scrollLeft;
68
+ return scrollbarX ? "paddingLeft" : "paddingRight";
69
+ }
70
+ function preventBodyScroll(options = {}) {
71
+ var _a;
72
+ const { document: docProp, disabled } = options;
73
+ if (disabled)
74
+ return;
75
+ const doc = docProp != null ? docProp : document;
76
+ const win = (_a = doc == null ? void 0 : doc.defaultView) != null ? _a : window;
77
+ const { documentElement, body } = doc;
78
+ const locked = body.hasAttribute(identifier);
79
+ if (locked)
80
+ return;
81
+ body.setAttribute(identifier, "");
82
+ const scrollbarWidth = win.innerWidth - documentElement.clientWidth;
83
+ const setScrollbarWidthProperty = () => setCSSProperty(documentElement, "--scrollbar-width", `${scrollbarWidth}px`);
84
+ const paddingProperty = getPaddingProperty(documentElement);
85
+ const setStyle = () => assignStyle(body, {
86
+ overflow: "hidden",
87
+ [paddingProperty]: `${scrollbarWidth}px`
88
+ });
89
+ const setIOSStyle = () => {
90
+ var _a2, _b;
91
+ const { scrollX, scrollY, visualViewport } = win;
92
+ const offsetLeft = (_a2 = visualViewport == null ? void 0 : visualViewport.offsetLeft) != null ? _a2 : 0;
93
+ const offsetTop = (_b = visualViewport == null ? void 0 : visualViewport.offsetTop) != null ? _b : 0;
94
+ const restoreStyle = assignStyle(body, {
95
+ position: "fixed",
96
+ overflow: "hidden",
97
+ top: `${-(scrollY - Math.floor(offsetTop))}px`,
98
+ left: `${-(scrollX - Math.floor(offsetLeft))}px`,
99
+ right: "0",
100
+ [paddingProperty]: `${scrollbarWidth}px`
101
+ });
102
+ return () => {
103
+ restoreStyle();
104
+ win.scrollTo(scrollX, scrollY);
105
+ };
106
+ };
107
+ const cleanups = [setScrollbarWidthProperty(), isIos() ? setIOSStyle() : setStyle()];
108
+ return () => {
109
+ cleanups.forEach((cleanup) => cleanup());
110
+ body.removeAttribute(identifier);
111
+ };
112
+ }
113
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/index.ts", "../../core/src/array.ts", "../../core/src/guard.ts", "../../core/src/platform.ts", "../../core/src/events.ts", "../../core/src/functions.ts", "../../core/src/warning.ts"],
4
+ "sourcesContent": ["import { isIos } from \"@zag-js/utils\"\n\nconst identifier = \"data-scroll-lock\"\n\nfunction assignStyle(el: HTMLElement | null | undefined, style: Partial<CSSStyleDeclaration>) {\n if (!el) return () => {}\n const previousStyle = el.style.cssText\n Object.assign(el.style, style)\n return () => {\n el.style.cssText = previousStyle\n }\n}\n\nfunction setCSSProperty(el: HTMLElement | null | undefined, property: string, value: string) {\n if (!el) return () => {}\n const previousValue = el.style.getPropertyValue(property)\n el.style.setProperty(property, value)\n return () => {\n if (previousValue) {\n el.style.setProperty(property, previousValue)\n } else {\n el.style.removeProperty(property)\n }\n }\n}\n\nfunction getPaddingProperty(documentElement: HTMLElement) {\n // RTL <body> scrollbar\n const documentLeft = documentElement.getBoundingClientRect().left\n const scrollbarX = Math.round(documentLeft) + documentElement.scrollLeft\n return scrollbarX ? \"paddingLeft\" : \"paddingRight\"\n}\n\ninterface BodyScrollOptions {\n disabled?: boolean\n document?: Document\n}\n\nexport function preventBodyScroll(options: BodyScrollOptions = {}) {\n const { document: docProp, disabled } = options\n\n if (disabled) return\n\n const doc = docProp ?? document\n const win = doc?.defaultView ?? window\n const { documentElement, body } = doc\n\n const locked = body.hasAttribute(identifier)\n if (locked) return\n\n body.setAttribute(identifier, \"\")\n\n const scrollbarWidth = win.innerWidth - documentElement.clientWidth\n const setScrollbarWidthProperty = () => setCSSProperty(documentElement, \"--scrollbar-width\", `${scrollbarWidth}px`)\n const paddingProperty = getPaddingProperty(documentElement)\n\n const setStyle = () =>\n assignStyle(body, {\n overflow: \"hidden\",\n [paddingProperty]: `${scrollbarWidth}px`,\n })\n\n // Only iOS doesn't respect `overflow: hidden` on document.body\n const setIOSStyle = () => {\n const { scrollX, scrollY, visualViewport } = win\n\n // iOS 12 does not support `visuaViewport`.\n const offsetLeft = visualViewport?.offsetLeft ?? 0\n const offsetTop = visualViewport?.offsetTop ?? 0\n\n const restoreStyle = assignStyle(body, {\n position: \"fixed\",\n overflow: \"hidden\",\n top: `${-(scrollY - Math.floor(offsetTop))}px`,\n left: `${-(scrollX - Math.floor(offsetLeft))}px`,\n right: \"0\",\n [paddingProperty]: `${scrollbarWidth}px`,\n })\n\n return () => {\n restoreStyle()\n win.scrollTo(scrollX, scrollY)\n }\n }\n\n const cleanups = [setScrollbarWidthProperty(), isIos() ? setIOSStyle() : setStyle()]\n\n return () => {\n cleanups.forEach((cleanup) => cleanup())\n body.removeAttribute(identifier)\n }\n}\n", "export function toArray<T>(v: T | T[] | undefined | null): T[] {\n if (!v) return []\n return Array.isArray(v) ? v : [v]\n}\n\nexport const fromLength = (length: number) => Array.from(Array(length).keys())\n\nexport const first = <T>(v: T[]): T | undefined => v[0]\n\nexport const last = <T>(v: T[]): T | undefined => v[v.length - 1]\n\nexport const isEmpty = <T>(v: T[]): boolean => v.length === 0\n\nexport const has = <T>(v: T[], t: any): boolean => v.indexOf(t) !== -1\n\nexport const add = <T>(v: T[], ...items: T[]): T[] => v.concat(items)\n\nexport const remove = <T>(v: T[], item: T): T[] => removeAt(v, v.indexOf(item))\n\nexport const removeAt = <T>(v: T[], i: number): T[] => {\n if (i > -1) v.splice(i, 1)\n return v\n}\n\nexport function clear<T>(v: T[]): T[] {\n while (v.length > 0) v.pop()\n return v\n}\n\nexport type IndexOptions = {\n step?: number\n loop?: boolean\n}\n\nexport function nextIndex<T>(v: T[], idx: number, opts: IndexOptions = {}): number {\n const { step = 1, loop = true } = opts\n const next = idx + step\n const len = v.length\n const last = len - 1\n if (idx === -1) return step > 0 ? 0 : last\n if (next < 0) return loop ? last : 0\n if (next >= len) return loop ? 0 : idx > len ? len : idx\n return next\n}\n\nexport function next<T>(v: T[], idx: number, opts: IndexOptions = {}): T | undefined {\n return v[nextIndex(v, idx, opts)]\n}\n\nexport function prevIndex<T>(v: T[], idx: number, opts: IndexOptions = {}): number {\n const { step = 1, loop = true } = opts\n return nextIndex(v, idx, { step: -step, loop })\n}\n\nexport function prev<T>(v: T[], index: number, opts: IndexOptions = {}): T | undefined {\n return v[prevIndex(v, index, opts)]\n}\n\nexport const chunk = <T>(v: T[], size: number): T[][] => {\n const res: T[][] = []\n return v.reduce((rows, value, index) => {\n if (index % size === 0) rows.push([value])\n else last(rows)?.push(value)\n return rows\n }, res)\n}\n", "export const isDev = () => process.env.NODE_ENV !== \"production\"\nexport const isDom = () => typeof window !== \"undefined\"\n\nexport const isArray = (v: any): v is any[] => Array.isArray(v)\nexport const isBoolean = (v: any): v is boolean => v === true || v === false\nexport const isObject = (v: any): v is Record<string, any> => !(v == null || typeof v !== \"object\" || isArray(v))\nexport const isNumber = (v: any): v is number => typeof v === \"number\" && !Number.isNaN(v)\nexport const isString = (v: any): v is string => typeof v === \"string\"\nexport const isFunction = (v: any): v is Function => typeof v === \"function\"\n\nexport const hasProp = <T extends string>(obj: any, prop: T): obj is Record<T, any> =>\n Object.prototype.hasOwnProperty.call(obj, prop)\n", "import { isDom } from \"./guard\"\n\nexport function getPlatform() {\n const agent = (navigator as any).userAgentData\n return agent?.platform ?? navigator.platform\n}\n\nconst pt = (v: RegExp) => isDom() && v.test(getPlatform())\nconst ua = (v: RegExp) => isDom() && v.test(navigator.userAgent)\nconst vn = (v: RegExp) => isDom() && v.test(navigator.vendor)\n\nexport const isTouchDevice = isDom() && !!navigator.maxTouchPoints\nexport const isMac = () => pt(/^Mac/) && !isTouchDevice\nexport const isIPhone = () => pt(/^iPhone/)\nexport const isSafari = () => isApple() && vn(/apple/i)\nexport const isFirefox = () => ua(/firefox\\//i)\nexport const isApple = () => pt(/mac|iphone|ipad|ipod/i)\nexport const isIos = () => isApple() && !isMac()\n", "import { hasProp, isDom, isObject } from \"./guard\"\nimport { isMac } from \"./platform\"\n\nexport const supportsPointerEvent = () => isDom() && window.onpointerdown === null\nexport const supportsTouchEvent = () => isDom() && window.ontouchstart === null\nexport const supportsMouseEvent = () => isDom() && window.onmousedown === null\n\nexport const isMouseEvent = (v: any): v is MouseEvent => isObject(v) && hasProp(v, \"button\")\nexport const isTouchEvent = (v: any): v is TouchEvent => isObject(v) && hasProp(v, \"touches\")\nexport const isLeftClick = (v: { button: number }) => v.button === 0\nexport const isRightClick = (v: { button: number }) => v.button === 2\nexport const isModifiedEvent = (v: Pick<KeyboardEvent, \"ctrlKey\" | \"metaKey\" | \"altKey\">) =>\n v.ctrlKey || v.altKey || v.metaKey\n\nexport const isCtrlKey = (v: Pick<KeyboardEvent, \"ctrlKey\" | \"metaKey\">) =>\n isMac() ? v.metaKey && !v.ctrlKey : v.ctrlKey && !v.metaKey\n", "export const runIfFn = <T>(\n v: T | undefined,\n ...a: T extends (...a: any[]) => void ? Parameters<T> : never\n): T extends (...a: any[]) => void ? NonNullable<ReturnType<T>> : NonNullable<T> => {\n const res = typeof v === \"function\" ? v(...a) : v\n return res ?? undefined\n}\n\nexport const cast = <T>(v: unknown): T => v as T\n\nexport const noop = () => {}\n\nexport const pipe =\n <T>(...fns: Array<(a: T) => T>) =>\n (v: T) =>\n fns.reduce((a, b) => b(a), v)\n\nexport const callAll =\n <T extends (...a: any[]) => void>(...fns: (T | undefined)[]) =>\n (...a: Parameters<T>) => {\n fns.forEach(function (fn) {\n fn?.(...a)\n })\n }\n\nexport const uuid = /*#__PURE__*/ (() => {\n let id = 0\n return () => {\n id++\n return id.toString(36)\n }\n})()\n\nexport function merge<T, U>(origin: T, patch: U): T & U {\n if (!(typeof patch === \"object\")) return patch as any\n const result = !(typeof origin === \"object\") ? {} : Object.assign({}, origin)\n for (const key of Object.keys(patch)) {\n const value = patch[key]\n const src = result[key]\n if (value === null) delete result[key]\n else if (Array.isArray(value) || Array.isArray(src)) result[key] = (src || []).concat(value || [])\n else result[key] = merge(src, value)\n }\n return result as any\n}\n", "export function warn(m: string): void\nexport function warn(c: boolean, m: string): void\nexport function warn(...a: any[]): void {\n const m = a.length === 1 ? a[0] : a[1]\n const c = a.length === 2 ? a[0] : true\n if (c && process.env.NODE_ENV !== \"production\") {\n console.warn(m)\n }\n}\n\nexport function invariant(m: string): void\nexport function invariant(c: boolean, m: string): void\nexport function invariant(...a: any[]): void {\n const m = a.length === 1 ? a[0] : a[1]\n const c = a.length === 2 ? a[0] : true\n if (c && process.env.NODE_ENV !== \"production\") {\n throw new Error(m)\n }\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;AECO,IAAM,QAAQ,MAAM,OAAO,WAAW;ACCtC,uBAAuB;AAF9B,MAAA;AAGE,QAAM,QAAS,UAAkB;AACjC,SAAO,MAAA,SAAA,OAAA,SAAA,MAAO,aAAP,OAAA,KAAmB,UAAU;AACtC;AAEA,IAAM,KAAK,CAAC,MAAc,MAAM,KAAK,EAAE,KAAK,YAAY,CAAC;AAIlD,IAAM,gBAAgB,MAAM,KAAK,CAAC,CAAC,UAAU;AAC7C,IAAM,QAAQ,MAAM,GAAG,MAAM,KAAK,CAAC;AAInC,IAAM,UAAU,MAAM,GAAG,uBAAuB;AAChD,IAAM,QAAQ,MAAM,QAAQ,KAAK,CAAC,MAAM;;;AHf/C,IAAM,aAAa;AAEnB,qBAAqB,IAAoC,OAAqC;AAC5F,MAAI,CAAC;AAAI,WAAO,MAAM;AAAA,IAAC;AACvB,QAAM,gBAAgB,GAAG,MAAM;AAC/B,SAAO,OAAO,GAAG,OAAO,KAAK;AAC7B,SAAO,MAAM;AACX,OAAG,MAAM,UAAU;AAAA,EACrB;AACF;AAEA,wBAAwB,IAAoC,UAAkB,OAAe;AAC3F,MAAI,CAAC;AAAI,WAAO,MAAM;AAAA,IAAC;AACvB,QAAM,gBAAgB,GAAG,MAAM,iBAAiB,QAAQ;AACxD,KAAG,MAAM,YAAY,UAAU,KAAK;AACpC,SAAO,MAAM;AACX,QAAI,eAAe;AACjB,SAAG,MAAM,YAAY,UAAU,aAAa;AAAA,IAC9C,OAAO;AACL,SAAG,MAAM,eAAe,QAAQ;AAAA,IAClC;AAAA,EACF;AACF;AAEA,4BAA4B,iBAA8B;AAExD,QAAM,eAAe,gBAAgB,sBAAsB,EAAE;AAC7D,QAAM,aAAa,KAAK,MAAM,YAAY,IAAI,gBAAgB;AAC9D,SAAO,aAAa,gBAAgB;AACtC;AAOO,2BAA2B,UAA6B,CAAC,GAAG;AAtCnE;AAuCE,QAAM,EAAE,UAAU,SAAS,aAAa;AAExC,MAAI;AAAU;AAEd,QAAM,MAAM,4BAAW;AACvB,QAAM,MAAM,iCAAK,gBAAL,YAAoB;AAChC,QAAM,EAAE,iBAAiB,SAAS;AAElC,QAAM,SAAS,KAAK,aAAa,UAAU;AAC3C,MAAI;AAAQ;AAEZ,OAAK,aAAa,YAAY,EAAE;AAEhC,QAAM,iBAAiB,IAAI,aAAa,gBAAgB;AACxD,QAAM,4BAA4B,MAAM,eAAe,iBAAiB,qBAAqB,GAAG,kBAAkB;AAClH,QAAM,kBAAkB,mBAAmB,eAAe;AAE1D,QAAM,WAAW,MACf,YAAY,MAAM;AAAA,IAChB,UAAU;AAAA,KACT,kBAAkB,GAAG;AAAA,EACxB,CAAC;AAGH,QAAM,cAAc,MAAM;AA/D5B;AAgEI,UAAM,EAAE,SAAS,SAAS,mBAAmB;AAG7C,UAAM,aAAa,wDAAgB,eAAhB,aAA8B;AACjD,UAAM,YAAY,uDAAgB,cAAhB,YAA6B;AAE/C,UAAM,eAAe,YAAY,MAAM;AAAA,MACrC,UAAU;AAAA,MACV,UAAU;AAAA,MACV,KAAK,GAAG,CAAE,WAAU,KAAK,MAAM,SAAS;AAAA,MACxC,MAAM,GAAG,CAAE,WAAU,KAAK,MAAM,UAAU;AAAA,MAC1C,OAAO;AAAA,OACN,kBAAkB,GAAG;AAAA,IACxB,CAAC;AAED,WAAO,MAAM;AACX,mBAAa;AACb,UAAI,SAAS,SAAS,OAAO;AAAA,IAC/B;AAAA,EACF;AAEA,QAAM,WAAW,CAAC,0BAA0B,GAAG,MAAM,IAAI,YAAY,IAAI,SAAS,CAAC;AAEnF,SAAO,MAAM;AACX,aAAS,QAAQ,CAAC,YAAY,QAAQ,CAAC;AACvC,SAAK,gBAAgB,UAAU;AAAA,EACjC;AACF;",
6
+ "names": []
7
+ }
package/dist/index.mjs ADDED
@@ -0,0 +1,91 @@
1
+ // ../core/dist/index.mjs
2
+ var isDom = () => typeof window !== "undefined";
3
+ function getPlatform() {
4
+ var _a;
5
+ const agent = navigator.userAgentData;
6
+ return (_a = agent == null ? void 0 : agent.platform) != null ? _a : navigator.platform;
7
+ }
8
+ var pt = (v) => isDom() && v.test(getPlatform());
9
+ var isTouchDevice = isDom() && !!navigator.maxTouchPoints;
10
+ var isMac = () => pt(/^Mac/) && !isTouchDevice;
11
+ var isApple = () => pt(/mac|iphone|ipad|ipod/i);
12
+ var isIos = () => isApple() && !isMac();
13
+
14
+ // src/index.ts
15
+ var identifier = "data-scroll-lock";
16
+ function assignStyle(el, style) {
17
+ if (!el)
18
+ return () => {
19
+ };
20
+ const previousStyle = el.style.cssText;
21
+ Object.assign(el.style, style);
22
+ return () => {
23
+ el.style.cssText = previousStyle;
24
+ };
25
+ }
26
+ function setCSSProperty(el, property, value) {
27
+ if (!el)
28
+ return () => {
29
+ };
30
+ const previousValue = el.style.getPropertyValue(property);
31
+ el.style.setProperty(property, value);
32
+ return () => {
33
+ if (previousValue) {
34
+ el.style.setProperty(property, previousValue);
35
+ } else {
36
+ el.style.removeProperty(property);
37
+ }
38
+ };
39
+ }
40
+ function getPaddingProperty(documentElement) {
41
+ const documentLeft = documentElement.getBoundingClientRect().left;
42
+ const scrollbarX = Math.round(documentLeft) + documentElement.scrollLeft;
43
+ return scrollbarX ? "paddingLeft" : "paddingRight";
44
+ }
45
+ function preventBodyScroll(options = {}) {
46
+ var _a;
47
+ const { document: docProp, disabled } = options;
48
+ if (disabled)
49
+ return;
50
+ const doc = docProp != null ? docProp : document;
51
+ const win = (_a = doc == null ? void 0 : doc.defaultView) != null ? _a : window;
52
+ const { documentElement, body } = doc;
53
+ const locked = body.hasAttribute(identifier);
54
+ if (locked)
55
+ return;
56
+ body.setAttribute(identifier, "");
57
+ const scrollbarWidth = win.innerWidth - documentElement.clientWidth;
58
+ const setScrollbarWidthProperty = () => setCSSProperty(documentElement, "--scrollbar-width", `${scrollbarWidth}px`);
59
+ const paddingProperty = getPaddingProperty(documentElement);
60
+ const setStyle = () => assignStyle(body, {
61
+ overflow: "hidden",
62
+ [paddingProperty]: `${scrollbarWidth}px`
63
+ });
64
+ const setIOSStyle = () => {
65
+ var _a2, _b;
66
+ const { scrollX, scrollY, visualViewport } = win;
67
+ const offsetLeft = (_a2 = visualViewport == null ? void 0 : visualViewport.offsetLeft) != null ? _a2 : 0;
68
+ const offsetTop = (_b = visualViewport == null ? void 0 : visualViewport.offsetTop) != null ? _b : 0;
69
+ const restoreStyle = assignStyle(body, {
70
+ position: "fixed",
71
+ overflow: "hidden",
72
+ top: `${-(scrollY - Math.floor(offsetTop))}px`,
73
+ left: `${-(scrollX - Math.floor(offsetLeft))}px`,
74
+ right: "0",
75
+ [paddingProperty]: `${scrollbarWidth}px`
76
+ });
77
+ return () => {
78
+ restoreStyle();
79
+ win.scrollTo(scrollX, scrollY);
80
+ };
81
+ };
82
+ const cleanups = [setScrollbarWidthProperty(), isIos() ? setIOSStyle() : setStyle()];
83
+ return () => {
84
+ cleanups.forEach((cleanup) => cleanup());
85
+ body.removeAttribute(identifier);
86
+ };
87
+ }
88
+ export {
89
+ preventBodyScroll
90
+ };
91
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../core/src/array.ts", "../../core/src/guard.ts", "../../core/src/platform.ts", "../../core/src/events.ts", "../../core/src/functions.ts", "../../core/src/warning.ts", "../src/index.ts"],
4
+ "sourcesContent": ["export function toArray<T>(v: T | T[] | undefined | null): T[] {\n if (!v) return []\n return Array.isArray(v) ? v : [v]\n}\n\nexport const fromLength = (length: number) => Array.from(Array(length).keys())\n\nexport const first = <T>(v: T[]): T | undefined => v[0]\n\nexport const last = <T>(v: T[]): T | undefined => v[v.length - 1]\n\nexport const isEmpty = <T>(v: T[]): boolean => v.length === 0\n\nexport const has = <T>(v: T[], t: any): boolean => v.indexOf(t) !== -1\n\nexport const add = <T>(v: T[], ...items: T[]): T[] => v.concat(items)\n\nexport const remove = <T>(v: T[], item: T): T[] => removeAt(v, v.indexOf(item))\n\nexport const removeAt = <T>(v: T[], i: number): T[] => {\n if (i > -1) v.splice(i, 1)\n return v\n}\n\nexport function clear<T>(v: T[]): T[] {\n while (v.length > 0) v.pop()\n return v\n}\n\nexport type IndexOptions = {\n step?: number\n loop?: boolean\n}\n\nexport function nextIndex<T>(v: T[], idx: number, opts: IndexOptions = {}): number {\n const { step = 1, loop = true } = opts\n const next = idx + step\n const len = v.length\n const last = len - 1\n if (idx === -1) return step > 0 ? 0 : last\n if (next < 0) return loop ? last : 0\n if (next >= len) return loop ? 0 : idx > len ? len : idx\n return next\n}\n\nexport function next<T>(v: T[], idx: number, opts: IndexOptions = {}): T | undefined {\n return v[nextIndex(v, idx, opts)]\n}\n\nexport function prevIndex<T>(v: T[], idx: number, opts: IndexOptions = {}): number {\n const { step = 1, loop = true } = opts\n return nextIndex(v, idx, { step: -step, loop })\n}\n\nexport function prev<T>(v: T[], index: number, opts: IndexOptions = {}): T | undefined {\n return v[prevIndex(v, index, opts)]\n}\n\nexport const chunk = <T>(v: T[], size: number): T[][] => {\n const res: T[][] = []\n return v.reduce((rows, value, index) => {\n if (index % size === 0) rows.push([value])\n else last(rows)?.push(value)\n return rows\n }, res)\n}\n", "export const isDev = () => process.env.NODE_ENV !== \"production\"\nexport const isDom = () => typeof window !== \"undefined\"\n\nexport const isArray = (v: any): v is any[] => Array.isArray(v)\nexport const isBoolean = (v: any): v is boolean => v === true || v === false\nexport const isObject = (v: any): v is Record<string, any> => !(v == null || typeof v !== \"object\" || isArray(v))\nexport const isNumber = (v: any): v is number => typeof v === \"number\" && !Number.isNaN(v)\nexport const isString = (v: any): v is string => typeof v === \"string\"\nexport const isFunction = (v: any): v is Function => typeof v === \"function\"\n\nexport const hasProp = <T extends string>(obj: any, prop: T): obj is Record<T, any> =>\n Object.prototype.hasOwnProperty.call(obj, prop)\n", "import { isDom } from \"./guard\"\n\nexport function getPlatform() {\n const agent = (navigator as any).userAgentData\n return agent?.platform ?? navigator.platform\n}\n\nconst pt = (v: RegExp) => isDom() && v.test(getPlatform())\nconst ua = (v: RegExp) => isDom() && v.test(navigator.userAgent)\nconst vn = (v: RegExp) => isDom() && v.test(navigator.vendor)\n\nexport const isTouchDevice = isDom() && !!navigator.maxTouchPoints\nexport const isMac = () => pt(/^Mac/) && !isTouchDevice\nexport const isIPhone = () => pt(/^iPhone/)\nexport const isSafari = () => isApple() && vn(/apple/i)\nexport const isFirefox = () => ua(/firefox\\//i)\nexport const isApple = () => pt(/mac|iphone|ipad|ipod/i)\nexport const isIos = () => isApple() && !isMac()\n", "import { hasProp, isDom, isObject } from \"./guard\"\nimport { isMac } from \"./platform\"\n\nexport const supportsPointerEvent = () => isDom() && window.onpointerdown === null\nexport const supportsTouchEvent = () => isDom() && window.ontouchstart === null\nexport const supportsMouseEvent = () => isDom() && window.onmousedown === null\n\nexport const isMouseEvent = (v: any): v is MouseEvent => isObject(v) && hasProp(v, \"button\")\nexport const isTouchEvent = (v: any): v is TouchEvent => isObject(v) && hasProp(v, \"touches\")\nexport const isLeftClick = (v: { button: number }) => v.button === 0\nexport const isRightClick = (v: { button: number }) => v.button === 2\nexport const isModifiedEvent = (v: Pick<KeyboardEvent, \"ctrlKey\" | \"metaKey\" | \"altKey\">) =>\n v.ctrlKey || v.altKey || v.metaKey\n\nexport const isCtrlKey = (v: Pick<KeyboardEvent, \"ctrlKey\" | \"metaKey\">) =>\n isMac() ? v.metaKey && !v.ctrlKey : v.ctrlKey && !v.metaKey\n", "export const runIfFn = <T>(\n v: T | undefined,\n ...a: T extends (...a: any[]) => void ? Parameters<T> : never\n): T extends (...a: any[]) => void ? NonNullable<ReturnType<T>> : NonNullable<T> => {\n const res = typeof v === \"function\" ? v(...a) : v\n return res ?? undefined\n}\n\nexport const cast = <T>(v: unknown): T => v as T\n\nexport const noop = () => {}\n\nexport const pipe =\n <T>(...fns: Array<(a: T) => T>) =>\n (v: T) =>\n fns.reduce((a, b) => b(a), v)\n\nexport const callAll =\n <T extends (...a: any[]) => void>(...fns: (T | undefined)[]) =>\n (...a: Parameters<T>) => {\n fns.forEach(function (fn) {\n fn?.(...a)\n })\n }\n\nexport const uuid = /*#__PURE__*/ (() => {\n let id = 0\n return () => {\n id++\n return id.toString(36)\n }\n})()\n\nexport function merge<T, U>(origin: T, patch: U): T & U {\n if (!(typeof patch === \"object\")) return patch as any\n const result = !(typeof origin === \"object\") ? {} : Object.assign({}, origin)\n for (const key of Object.keys(patch)) {\n const value = patch[key]\n const src = result[key]\n if (value === null) delete result[key]\n else if (Array.isArray(value) || Array.isArray(src)) result[key] = (src || []).concat(value || [])\n else result[key] = merge(src, value)\n }\n return result as any\n}\n", "export function warn(m: string): void\nexport function warn(c: boolean, m: string): void\nexport function warn(...a: any[]): void {\n const m = a.length === 1 ? a[0] : a[1]\n const c = a.length === 2 ? a[0] : true\n if (c && process.env.NODE_ENV !== \"production\") {\n console.warn(m)\n }\n}\n\nexport function invariant(m: string): void\nexport function invariant(c: boolean, m: string): void\nexport function invariant(...a: any[]): void {\n const m = a.length === 1 ? a[0] : a[1]\n const c = a.length === 2 ? a[0] : true\n if (c && process.env.NODE_ENV !== \"production\") {\n throw new Error(m)\n }\n}\n", "import { isIos } from \"@zag-js/utils\"\n\nconst identifier = \"data-scroll-lock\"\n\nfunction assignStyle(el: HTMLElement | null | undefined, style: Partial<CSSStyleDeclaration>) {\n if (!el) return () => {}\n const previousStyle = el.style.cssText\n Object.assign(el.style, style)\n return () => {\n el.style.cssText = previousStyle\n }\n}\n\nfunction setCSSProperty(el: HTMLElement | null | undefined, property: string, value: string) {\n if (!el) return () => {}\n const previousValue = el.style.getPropertyValue(property)\n el.style.setProperty(property, value)\n return () => {\n if (previousValue) {\n el.style.setProperty(property, previousValue)\n } else {\n el.style.removeProperty(property)\n }\n }\n}\n\nfunction getPaddingProperty(documentElement: HTMLElement) {\n // RTL <body> scrollbar\n const documentLeft = documentElement.getBoundingClientRect().left\n const scrollbarX = Math.round(documentLeft) + documentElement.scrollLeft\n return scrollbarX ? \"paddingLeft\" : \"paddingRight\"\n}\n\ninterface BodyScrollOptions {\n disabled?: boolean\n document?: Document\n}\n\nexport function preventBodyScroll(options: BodyScrollOptions = {}) {\n const { document: docProp, disabled } = options\n\n if (disabled) return\n\n const doc = docProp ?? document\n const win = doc?.defaultView ?? window\n const { documentElement, body } = doc\n\n const locked = body.hasAttribute(identifier)\n if (locked) return\n\n body.setAttribute(identifier, \"\")\n\n const scrollbarWidth = win.innerWidth - documentElement.clientWidth\n const setScrollbarWidthProperty = () => setCSSProperty(documentElement, \"--scrollbar-width\", `${scrollbarWidth}px`)\n const paddingProperty = getPaddingProperty(documentElement)\n\n const setStyle = () =>\n assignStyle(body, {\n overflow: \"hidden\",\n [paddingProperty]: `${scrollbarWidth}px`,\n })\n\n // Only iOS doesn't respect `overflow: hidden` on document.body\n const setIOSStyle = () => {\n const { scrollX, scrollY, visualViewport } = win\n\n // iOS 12 does not support `visuaViewport`.\n const offsetLeft = visualViewport?.offsetLeft ?? 0\n const offsetTop = visualViewport?.offsetTop ?? 0\n\n const restoreStyle = assignStyle(body, {\n position: \"fixed\",\n overflow: \"hidden\",\n top: `${-(scrollY - Math.floor(offsetTop))}px`,\n left: `${-(scrollX - Math.floor(offsetLeft))}px`,\n right: \"0\",\n [paddingProperty]: `${scrollbarWidth}px`,\n })\n\n return () => {\n restoreStyle()\n win.scrollTo(scrollX, scrollY)\n }\n }\n\n const cleanups = [setScrollbarWidthProperty(), isIos() ? setIOSStyle() : setStyle()]\n\n return () => {\n cleanups.forEach((cleanup) => cleanup())\n body.removeAttribute(identifier)\n }\n}\n"],
5
+ "mappings": ";ACCO,IAAM,QAAQ,MAAM,OAAO,WAAW;ACCtC,uBAAuB;AAF9B,MAAA;AAGE,QAAM,QAAS,UAAkB;AACjC,SAAO,MAAA,SAAA,OAAA,SAAA,MAAO,aAAP,OAAA,KAAmB,UAAU;AACtC;AAEA,IAAM,KAAK,CAAC,MAAc,MAAM,KAAK,EAAE,KAAK,YAAY,CAAC;AAIlD,IAAM,gBAAgB,MAAM,KAAK,CAAC,CAAC,UAAU;AAC7C,IAAM,QAAQ,MAAM,GAAG,MAAM,KAAK,CAAC;AAInC,IAAM,UAAU,MAAM,GAAG,uBAAuB;AAChD,IAAM,QAAQ,MAAM,QAAQ,KAAK,CAAC,MAAM;;;AIf/C,IAAM,aAAa;AAEnB,qBAAqB,IAAoC,OAAqC;AAC5F,MAAI,CAAC;AAAI,WAAO,MAAM;AAAA,IAAC;AACvB,QAAM,gBAAgB,GAAG,MAAM;AAC/B,SAAO,OAAO,GAAG,OAAO,KAAK;AAC7B,SAAO,MAAM;AACX,OAAG,MAAM,UAAU;AAAA,EACrB;AACF;AAEA,wBAAwB,IAAoC,UAAkB,OAAe;AAC3F,MAAI,CAAC;AAAI,WAAO,MAAM;AAAA,IAAC;AACvB,QAAM,gBAAgB,GAAG,MAAM,iBAAiB,QAAQ;AACxD,KAAG,MAAM,YAAY,UAAU,KAAK;AACpC,SAAO,MAAM;AACX,QAAI,eAAe;AACjB,SAAG,MAAM,YAAY,UAAU,aAAa;AAAA,IAC9C,OAAO;AACL,SAAG,MAAM,eAAe,QAAQ;AAAA,IAClC;AAAA,EACF;AACF;AAEA,4BAA4B,iBAA8B;AAExD,QAAM,eAAe,gBAAgB,sBAAsB,EAAE;AAC7D,QAAM,aAAa,KAAK,MAAM,YAAY,IAAI,gBAAgB;AAC9D,SAAO,aAAa,gBAAgB;AACtC;AAOO,2BAA2B,UAA6B,CAAC,GAAG;AAtCnE;AAuCE,QAAM,EAAE,UAAU,SAAS,aAAa;AAExC,MAAI;AAAU;AAEd,QAAM,MAAM,4BAAW;AACvB,QAAM,MAAM,iCAAK,gBAAL,YAAoB;AAChC,QAAM,EAAE,iBAAiB,SAAS;AAElC,QAAM,SAAS,KAAK,aAAa,UAAU;AAC3C,MAAI;AAAQ;AAEZ,OAAK,aAAa,YAAY,EAAE;AAEhC,QAAM,iBAAiB,IAAI,aAAa,gBAAgB;AACxD,QAAM,4BAA4B,MAAM,eAAe,iBAAiB,qBAAqB,GAAG,kBAAkB;AAClH,QAAM,kBAAkB,mBAAmB,eAAe;AAE1D,QAAM,WAAW,MACf,YAAY,MAAM;AAAA,IAChB,UAAU;AAAA,KACT,kBAAkB,GAAG;AAAA,EACxB,CAAC;AAGH,QAAM,cAAc,MAAM;AA/D5B;AAgEI,UAAM,EAAE,SAAS,SAAS,mBAAmB;AAG7C,UAAM,aAAa,wDAAgB,eAAhB,aAA8B;AACjD,UAAM,YAAY,uDAAgB,cAAhB,YAA6B;AAE/C,UAAM,eAAe,YAAY,MAAM;AAAA,MACrC,UAAU;AAAA,MACV,UAAU;AAAA,MACV,KAAK,GAAG,CAAE,WAAU,KAAK,MAAM,SAAS;AAAA,MACxC,MAAM,GAAG,CAAE,WAAU,KAAK,MAAM,UAAU;AAAA,MAC1C,OAAO;AAAA,OACN,kBAAkB,GAAG;AAAA,IACxB,CAAC;AAED,WAAO,MAAM;AACX,mBAAa;AACb,UAAI,SAAS,SAAS,OAAO;AAAA,IAC/B;AAAA,EACF;AAEA,QAAM,WAAW,CAAC,0BAA0B,GAAG,MAAM,IAAI,YAAY,IAAI,SAAS,CAAC;AAEnF,SAAO,MAAM;AACX,aAAS,QAAQ,CAAC,YAAY,QAAQ,CAAC;AACvC,SAAK,gBAAgB,UAAU;AAAA,EACjC;AACF;",
6
+ "names": []
7
+ }
package/package.json ADDED
@@ -0,0 +1,39 @@
1
+ {
2
+ "name": "@zag-js/remove-scroll",
3
+ "version": "0.0.0-dev-20220604123458",
4
+ "description": "JavaScript utility to remove scroll on body",
5
+ "keywords": [
6
+ "js",
7
+ "utils",
8
+ "remove-scroll"
9
+ ],
10
+ "author": "Segun Adebayo <sage@adebayosegun.com>",
11
+ "homepage": "https://github.com/chakra-ui/zag#readme",
12
+ "license": "MIT",
13
+ "main": "dist/index.js",
14
+ "module": "dist/index.mjs",
15
+ "types": "dist/index.d.ts",
16
+ "repository": "https://github.com/chakra-ui/zag/tree/main/packages/utilities/remove-scroll",
17
+ "sideEffects": false,
18
+ "files": [
19
+ "dist/**/*"
20
+ ],
21
+ "scripts": {
22
+ "build:fast": "yarn zag build",
23
+ "start": "yarn zag build --watch",
24
+ "build": "yarn zag build --prod",
25
+ "test": "jest --config ../../../jest.config.js --rootDir tests",
26
+ "lint": "eslint src --ext .ts,.tsx",
27
+ "test:ci": "yarn test --ci --runInBand --updateSnapshot",
28
+ "test:watch": "yarn test --watchAll"
29
+ },
30
+ "publishConfig": {
31
+ "access": "public"
32
+ },
33
+ "dependencies": {
34
+ "@zag-js/utils": "0.0.0-dev-20220604123458"
35
+ },
36
+ "bugs": {
37
+ "url": "https://github.com/chakra-ui/zag/issues"
38
+ }
39
+ }