pax_global_header00006660000000000000000000000064151125171300014506gustar00rootroot0000000000000052 comment=ef5c312e4c1c6bc5d4cd60b03261d686b8cb165f theKashey-react-remove-scroll-b5d57a4/000077500000000000000000000000001511251713000177335ustar00rootroot00000000000000theKashey-react-remove-scroll-b5d57a4/.eslintrc.js000066400000000000000000000035011511251713000221710ustar00rootroot00000000000000module.exports = { extends: ['plugin:@typescript-eslint/recommended', 'plugin:import/typescript', 'plugin:react-hooks/recommended'], parser: '@typescript-eslint/parser', plugins: ['@typescript-eslint', 'prettier', 'import'], rules: { '@typescript-eslint/ban-ts-comment': 0, '@typescript-eslint/ban-ts-ignore': 0, '@typescript-eslint/no-var-requires': 0, '@typescript-eslint/camelcase': 0, 'import/order': [ 'error', { 'newlines-between': 'always-and-inside-groups', alphabetize: { order: 'asc', }, groups: ['builtin', 'external', 'internal', ['parent', 'index', 'sibling']], }, ], 'padding-line-between-statements': [ 'error', // IMPORT { blankLine: 'always', prev: 'import', next: '*', }, { blankLine: 'any', prev: 'import', next: 'import', }, // EXPORT { blankLine: 'always', prev: '*', next: 'export', }, { blankLine: 'any', prev: 'export', next: 'export', }, { blankLine: 'always', prev: '*', next: ['const', 'let'], }, { blankLine: 'any', prev: ['const', 'let'], next: ['const', 'let'], }, // BLOCKS { blankLine: 'always', prev: ['block', 'block-like', 'class', 'function', 'multiline-expression'], next: '*', }, { blankLine: 'always', prev: '*', next: ['block', 'block-like', 'class', 'function', 'return', 'multiline-expression'], }, ], }, settings: { 'import/parsers': { '@typescript-eslint/parser': ['.ts', '.tsx'], }, 'import/resolver': { typescript: { alwaysTryTypes: true, }, }, }, }; theKashey-react-remove-scroll-b5d57a4/.github/000077500000000000000000000000001511251713000212735ustar00rootroot00000000000000theKashey-react-remove-scroll-b5d57a4/.github/stale.yml000066400000000000000000000012741511251713000231320ustar00rootroot00000000000000# Number of days of inactivity before an issue becomes stale daysUntilStale: 60 # Number of days of inactivity before a stale issue is closed daysUntilClose: 7 # Label to use when marking an issue as stale staleLabel: state # Comment to post when marking an issue as stale. Set to `false` to disable markComment: > This issue has been marked as "stale" because there has been no activity for 2 months. If you have any new information or would like to continue the discussion, please feel free to do so. If this issue got buried among other tasks, maybe this message will reignite the conversation. Otherwise, this issue will be closed in 7 days. Thank you for your contributions so far. theKashey-react-remove-scroll-b5d57a4/.gitignore000066400000000000000000000000671511251713000217260ustar00rootroot00000000000000node_modules/ /dist/ .DS_Store coverage/ yarn-error.logtheKashey-react-remove-scroll-b5d57a4/.npmignore000066400000000000000000000000671511251713000217350ustar00rootroot00000000000000node_modules/ npm-debug.log .DS_Store example __tests__theKashey-react-remove-scroll-b5d57a4/.npmrc000066400000000000000000000000431511251713000210500ustar00rootroot00000000000000registry=https://registry.npmjs.orgtheKashey-react-remove-scroll-b5d57a4/.nvmrc000066400000000000000000000000021511251713000210510ustar00rootroot0000000000000018theKashey-react-remove-scroll-b5d57a4/.size-limit000066400000000000000000000005511511251713000220230ustar00rootroot00000000000000[ { "path": "dist/es2015/index.js", "ignore": ["react-dom", "tslib", "use-sidecar"], "limit": "3.8 KB" }, { "path": "dist/es2015/sidecar.js", "ignore": ["react-dom", "tslib", "use-sidecar"], "limit": "3.1 KB" }, { "path": "dist/es2015/UI.js", "ignore": ["react-dom", "tslib", "use-sidecar"], "limit": "1.2 KB" } ]theKashey-react-remove-scroll-b5d57a4/.size.json000066400000000000000000000004751511251713000216640ustar00rootroot00000000000000[ { "name": "dist/es2015/index.js", "passed": true, "size": 3638, "sizeLimit": 3800 }, { "name": "dist/es2015/sidecar.js", "passed": true, "size": 3009, "sizeLimit": 3100 }, { "name": "dist/es2015/UI.js", "passed": true, "size": 1110, "sizeLimit": 1200 } ] theKashey-react-remove-scroll-b5d57a4/.storybook/000077500000000000000000000000001511251713000220445ustar00rootroot00000000000000theKashey-react-remove-scroll-b5d57a4/.storybook/.babelrc000066400000000000000000000003371511251713000234420ustar00rootroot00000000000000{ "sourceType": "unambiguous", "presets": [ [ "@babel/preset-env", { "shippedProposals": true, "loose": true } ], "@babel/preset-typescript", "@babel/preset-react" ] }theKashey-react-remove-scroll-b5d57a4/.storybook/main.js000066400000000000000000000002241511251713000233240ustar00rootroot00000000000000module.exports = { stories: ['../stories/*.stories.@(js|jsx|ts|tsx)'], framework: '@storybook/react', typescript: { check: false, }, }; theKashey-react-remove-scroll-b5d57a4/.storybook/preview.js000066400000000000000000000002571511251713000240670ustar00rootroot00000000000000export const parameters = { actions: { argTypesRegex: '^on[A-Z].*' }, controls: { matchers: { color: /(background|color)$/i, date: /Date$/, }, }, }; theKashey-react-remove-scroll-b5d57a4/.travis.yml000066400000000000000000000001571511251713000220470ustar00rootroot00000000000000language: node_js node_js: - '14' cache: yarn script: - yarn - yarn test:ci notifications: email: falsetheKashey-react-remove-scroll-b5d57a4/CHANGELOG.md000066400000000000000000000213261511251713000215500ustar00rootroot00000000000000## [2.6.2](https://github.com/theKashey/react-remove-scroll/compare/v2.6.1...v2.6.2) (2024-12-17) ## [2.6.1](https://github.com/theKashey/react-remove-scroll/compare/v2.6.0...v2.6.1) (2024-12-15) ### Bug Fixes - README typo ([a723e5b](https://github.com/theKashey/react-remove-scroll/commit/a723e5b03301bdd462c4f4c6166db6c772e24b55)) ### Features - add react v19 to peer deps ([6656c05](https://github.com/theKashey/react-remove-scroll/commit/6656c053018b5ff50342fc2182b090b4dc4c1229)) # [2.6.0](https://github.com/theKashey/react-remove-scroll/compare/v2.5.10...v2.6.0) (2024-09-08) ## [2.5.10](https://github.com/theKashey/react-remove-scroll/compare/v2.5.9...v2.5.10) (2024-05-12) ### Bug Fixes - correct behavior in shadow dom ([ea7a398](https://github.com/theKashey/react-remove-scroll/commit/ea7a398ffe624678fb0b9450ea8812ab6ebdb1b5)) - elementCanBeScrolled fails if node is not an HTMLElement ([baa56c3](https://github.com/theKashey/react-remove-scroll/commit/baa56c3daa7e1d6b802c6ba7f2efd989cc412a13)) ## [2.5.9](https://github.com/theKashey/react-remove-scroll/compare/v2.5.8...v2.5.9) (2024-03-16) ## [2.5.8](https://github.com/theKashey/react-remove-scroll/compare/v2.5.7...v2.5.8) (2024-03-16) ### Bug Fixes - update react-remove-scroll-bar to fix nested cases ([be1f247](https://github.com/theKashey/react-remove-scroll/commit/be1f247ef908faa15b569295726b164a0a026978)) ## [2.5.7](https://github.com/theKashey/react-remove-scroll/compare/v2.5.6...v2.5.7) (2023-10-10) ### Bug Fixes - correct edge case behavior on non zero browser zoom levels ([cd24189](https://github.com/theKashey/react-remove-scroll/commit/cd24189765f59074bba22cbf03ce5f80e2950c7d)) - correct shadow dom traversal ([55d302b](https://github.com/theKashey/react-remove-scroll/commit/55d302ba98f250eb366fc36337b4d4656889ae88)) ## [2.5.6](https://github.com/theKashey/react-remove-scroll/compare/v2.5.5...v2.5.6) (2023-04-30) ### Bug Fixes - pass gapMode to react-remove-scroll-bar ([04412b1](https://github.com/theKashey/react-remove-scroll/commit/04412b14b3f164a632e711998ba414f0a9929438)) ## [2.5.5](https://github.com/theKashey/react-remove-scroll/compare/v2.5.4...v2.5.5) (2022-07-03) ### Bug Fixes - add special treatment for textareas, fixes [#74](https://github.com/theKashey/react-remove-scroll/issues/74) ([af8fd75](https://github.com/theKashey/react-remove-scroll/commit/af8fd751a49d6deb9f40d79ecef9b030f291354e)) - do not prevent uncancelable events, fixes [#8](https://github.com/theKashey/react-remove-scroll/issues/8) ([9d12786](https://github.com/theKashey/react-remove-scroll/commit/9d127860addd39c7305aea9e57ee2f51cecd229d)) ## [2.5.4](https://github.com/theKashey/react-remove-scroll/compare/v2.5.3...v2.5.4) (2022-06-06) ### Bug Fixes - update react-remove-scroll-bar. Fixes [#71](https://github.com/theKashey/react-remove-scroll/issues/71) ([3f51035](https://github.com/theKashey/react-remove-scroll/commit/3f51035e5a433443657169ea8c61661acf301b14)) ## [2.5.3](https://github.com/theKashey/react-remove-scroll/compare/v2.5.2...v2.5.3) (2022-05-01) ### Bug Fixes - add ref to the public interface ([db99c0e](https://github.com/theKashey/react-remove-scroll/commit/db99c0e484fd67ee87a889d4cb939c5a43f2734a)) ## [2.5.2](https://github.com/theKashey/react-remove-scroll/compare/v2.5.1...v2.5.2) (2022-05-01) ### Bug Fixes - correct React 18 integration ([af8e23e](https://github.com/theKashey/react-remove-scroll/commit/af8e23e28be1d1fed917fc2967030d29680c2fc2)) ## [2.5.1](https://github.com/theKashey/react-remove-scroll/compare/v2.5.0...v2.5.1) (2022-04-19) ### Bug Fixes - restore entrypoints, fixes [#68](https://github.com/theKashey/react-remove-scroll/issues/68) ([6ef7d3c](https://github.com/theKashey/react-remove-scroll/commit/6ef7d3c8b935c9bc1eb75f1aa8e1ea6738ae2985)) # [2.5.0](https://github.com/theKashey/react-remove-scroll/compare/v2.4.4...v2.5.0) (2022-04-18) ### Bug Fixes - correct range input behavior, fixes [#64](https://github.com/theKashey/react-remove-scroll/issues/64) ([0bd6ca8](https://github.com/theKashey/react-remove-scroll/commit/0bd6ca85d014acc10ed37b6d3f9e70e1ee4e2c30)) ## [2.4.4](https://github.com/theKashey/react-remove-scroll/compare/v2.4.2...v2.4.4) (2022-02-12) ### Bug Fixes - correct lock behavior for RTL direction ([23457a7](https://github.com/theKashey/react-remove-scroll/commit/23457a7770e010b36b950057d90f496d12d8a93c)) - Scroll working in RTL ([fcae298](https://github.com/theKashey/react-remove-scroll/commit/fcae298d7d35de00ec35fd712bee54c7db2d491c)) - Skip shadow root when traversing up the dom tree ([eb6a5e7](https://github.com/theKashey/react-remove-scroll/commit/eb6a5e7ddc70432586c07e151e535d0e9d631833)) ## [2.4.2](https://github.com/theKashey/react-remove-scroll/compare/v2.4.1...v2.4.2) (2021-05-08) ## [2.4.1](https://github.com/theKashey/react-remove-scroll/compare/v2.4.0...v2.4.1) (2020-11-27) # [2.4.0](https://github.com/theKashey/react-remove-scroll/compare/v2.3.0...v2.4.0) (2020-08-13) ### Features - expose 'as' and 'style' props ([3022f26](https://github.com/theKashey/react-remove-scroll/commit/3022f26e811de6e6154298743159bfe9b18bf332)) # [2.3.0](https://github.com/theKashey/react-remove-scroll/compare/v2.2.0...v2.3.0) (2020-04-16) ### Features - support CSP ([60ce4bf](https://github.com/theKashey/react-remove-scroll/commit/60ce4bf25caf845090cc5ff952ae78d8dca7b587)) # [2.2.0](https://github.com/theKashey/react-remove-scroll/compare/v2.1.1...v2.2.0) (2019-10-17) ### Features - add allowPinchZoom property, fixes [#17](https://github.com/theKashey/react-remove-scroll/issues/17) ([2945796](https://github.com/theKashey/react-remove-scroll/commit/2945796612cdbdc36bb3a888c449e62908a3bea1)) ## [2.1.1](https://github.com/theKashey/react-remove-scroll/compare/v2.1.0...v2.1.1) (2019-10-13) ### Bug Fixes - pass all extra props to the underlaying element ([a022ce7](https://github.com/theKashey/react-remove-scroll/commit/a022ce7c088bdeb5b6db048cd8f4e3ea48ce1eb5)) # [2.1.0](https://github.com/theKashey/react-remove-scroll/compare/v2.0.4...v2.1.0) (2019-10-13) ### Features - allow ref forwarding ([55ecf2b](https://github.com/theKashey/react-remove-scroll/commit/55ecf2bc16cbba54064f7ac60b323fbf820e662c)) ## [2.0.4](https://github.com/theKashey/react-remove-scroll/compare/v2.0.3...v2.0.4) (2019-07-03) ### Bug Fixes - sidecar is a sideeffect ([86b3309](https://github.com/theKashey/react-remove-scroll/commit/86b330978198235e9d69088a35cae3597361c030)) ## [2.0.3](https://github.com/theKashey/react-remove-scroll/compare/v2.0.2...v2.0.3) (2019-07-02) ### Bug Fixes - cjs sidecar package ([1aaaf0b](https://github.com/theKashey/react-remove-scroll/commit/1aaaf0b2b6245705043b93525be5c522ba69ecdc)) ## [2.0.2](https://github.com/theKashey/react-remove-scroll/compare/v2.0.1...v2.0.2) (2019-06-29) ## [2.0.1](https://github.com/theKashey/react-remove-scroll/compare/v2.0.0...v2.0.1) (2019-06-29) ### Bug Fixes - remove self dependency ([2842cde](https://github.com/theKashey/react-remove-scroll/commit/2842cdebbcc22258e422c1c5c0fb6bbc544f4dd3)) # [2.0.0](https://github.com/theKashey/react-remove-scroll/compare/v1.0.8...v2.0.0) (2019-06-29) ### Features - introduce sidecar ([2ca7f59](https://github.com/theKashey/react-remove-scroll/commit/2ca7f59e86abc6e252422ec5cb6132281e945984)) ## [1.0.8](https://github.com/theKashey/react-remove-scroll/compare/v1.0.7...v1.0.8) (2019-05-05) ## [1.0.7](https://github.com/theKashey/react-remove-scroll/compare/v1.0.6...v1.0.7) (2019-05-04) ### Bug Fixes - force lock body scroll on scroll-free systems. fixes [#4](https://github.com/theKashey/react-remove-scroll/issues/4) ([c9c3209](https://github.com/theKashey/react-remove-scroll/commit/c9c320935c5cb0adb277d7dd5359295b80b6bf52)) ## [1.0.6](https://github.com/theKashey/react-remove-scroll/compare/v1.0.4...v1.0.6) (2019-04-15) ### Bug Fixes - overflowX was used for Y axis ([a4b2f33](https://github.com/theKashey/react-remove-scroll/commit/a4b2f3312755f705fdc71e5613cab7e41bd07035)) - support old refs ([a8be7c2](https://github.com/theKashey/react-remove-scroll/commit/a8be7c2966b81cdca6602993b1c8fcd53fb07db8)) ### Features - support shards ([67519f3](https://github.com/theKashey/react-remove-scroll/commit/67519f37bffea7efb45d24d25e2b269520450c7c)) ## [1.0.4](https://github.com/theKashey/react-remove-scroll/compare/v1.0.3...v1.0.4) (2019-02-26) ## [1.0.3](https://github.com/theKashey/react-remove-scroll/compare/v1.0.2...v1.0.3) (2019-02-06) ### Bug Fixes - detect overflow hidden ([aa848e6](https://github.com/theKashey/react-remove-scroll/commit/aa848e678bd57d20fd97b1e42ff62eabd631a237)) ## [1.0.2](https://github.com/theKashey/react-remove-scroll/compare/v1.0.1...v1.0.2) (2019-01-22) ### Bug Fixes - support stacked mode ([8c003ba](https://github.com/theKashey/react-remove-scroll/commit/8c003ba8388c4695e03ff3dfbab09e1cc1cf967a)) ## 1.0.1 (2019-01-22) theKashey-react-remove-scroll-b5d57a4/LICENSE000066400000000000000000000020571511251713000207440ustar00rootroot00000000000000MIT License Copyright (c) 2017 Anton Korzunov Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. theKashey-react-remove-scroll-b5d57a4/README.md000066400000000000000000000134631511251713000212210ustar00rootroot00000000000000

React-remove-📜


dont even scroll
Build status npm downloads bundle size
react-remove-scroll ==== [![NPM version](https://img.shields.io/npm/v/react-remove-scroll.svg)](https://www.npmjs.com/package/react-remove-scroll) Disables scroll outside of `children` node. - 🖱 mouse and touch devices friendly - 📈 vertical and horizontal - 📜 removes document scroll bar maintaining it space - ✅ support nested scrollable elements - 🕳 supports react-portals (uses React Event system) - ☠️ it could block literally any scroll anywhere # Usage Just wrap content, which should be scrollable, and everything else would not. ```js import {RemoveScroll} from 'react-remove-scroll'; Only this content would be scrollable ``` `RemoveScroll` accept following props - `children` - `[enabled]` - activate or deactivate component behaviour without removing it. - `[allowPinchZoom=false]` - enabled "pinch-n-zoom" behavior. By default it might be prevented. However - pinch and zoom might break "scroll isolation", and __disabled by default__. - `[noRelative=false]` - prevents setting `position: relative` on the body. - `[noIsolation=false]` - disables outer event capturing. Event capturing is React friendly and unlikely be a problem. But if you are using _shadowbox_ of some sort - you dont need it. - `[inert=false]` - ☠️(be careful) disables events the rest of page completely using `pointer-events` except the Lock(+shards). React portals not friendly, might lead to production issues. Enable only for __rare__ cases, when you have to disable scrollbars somewhere on the page(except body, Lock and shards). - `[forwardProps]` - will forward all props to the `children` - `[className]` - className for an internal div - `[removeScrollBar]` - to control scroll bar removal. Set to false, if you prefer to keep it (wheel and touch scroll is still disabled). # Size - (🧩 full) 1.7kb after compression (excluding tslib). --- - (👁 UI) __400b__, visual elements only - (🚗 sidecar) 1.5kb, side effects ```js import {sidecar} from "react-remove-scroll"; import {RemoveScroll} from 'react-remove-scroll/UI'; const sidecar = sidecar(() => import('react-remove-scroll/sidecar')); Will load logic from a sidecar when needed ``` > Consider setting `-webkit-overflow-scrolling: touch;` on a document level for a proper mobile experience. ## Internal div By default RemoveScroll will create a div to handle and capture events. You may specify `className` for it, if you need, or __remove it__. The following code samples will produce the same output ```js Only this content would be scrollable ``` ```js
//RemoveScroll will inject props to this div Only this content would be scrollable
``` Pick the first one if you don't need a second. ## Position:fixed elements To properly size these elements please add a special className to them. ```jsx import {RemoveScroll} from 'react-remove-scroll'; // to make "width: 100%"
// to make "right:0"
``` See [react-remove-scroll-bar](https://github.com/theKashey/react-remove-scroll-bar) documentation for details. ## More than one lock When stacked more is active (default) only one (last) component would be active. ## Over isolation That could happen - you disable scroll on the body, you are suppressing all scroll and wheel events, and you are ghosting the rest of the page by the `inert` prop. Only something inside Lock does exists for the browser, and that might be less than you expected. Dont forget about `shard`, dont forget - `inert` is not portals friendly, dont forget - you dont need over isolation in most of the cases. > just be careful! # Performance To do the job this library setup _non_ passive event listener. Chrome dev tools would complain about it, as a performance no-op. We have to use synchronous scroll/touch handler, and it may affect scrolling performance. Consider using `noIsolation` mode, if you have large scrollable areas. # Supported React versions - v1 supports React 15/16 - v2 requires 16.8.0+ (hooks) # Scroll-Locky This is a refactoring of another library - [react-scroll-locky](https://github.com/theKashey/react-scroll-locky) - to make package smaller and more react-portals friendly. ## See also - [react-focus-on](https://github.com/theKashey/react-focus-on) - Finite Modal creator (uses Scroll-Locky) underneath. - [react-locky](https://github.com/theKashey/react-locky) - React event canceler - [react-scrolllock](https://github.com/jossmac/react-scrolllock) - React scroll lock - [scroll-lock](https://github.com/FL3NKEY/scroll-lock) - DOM scroll lock - [body-scroll-lock](https://github.com/willmcpo/body-scroll-lock) - DOM scroll lock > This package is relative smaller(1), more react friendly(2), works with non zero body margins(3), and has a better "overscroll" management. # License MITtheKashey-react-remove-scroll-b5d57a4/UI/000077500000000000000000000000001511251713000202505ustar00rootroot00000000000000theKashey-react-remove-scroll-b5d57a4/UI/UI.d.ts000066400000000000000000000000411511251713000213520ustar00rootroot00000000000000export * from '../dist/es2015/UI'theKashey-react-remove-scroll-b5d57a4/UI/package.json000066400000000000000000000002601511251713000225340ustar00rootroot00000000000000{ "private": true, "main": "../dist/es5/UI.js", "jsnext:main": "../dist/es2015/UI.js", "module": "../dist/es2015/UI.js", "types": "UI.d.ts", "sideEffects": false } theKashey-react-remove-scroll-b5d57a4/__tests__/000077500000000000000000000000001511251713000216715ustar00rootroot00000000000000theKashey-react-remove-scroll-b5d57a4/__tests__/UI.tsx000066400000000000000000000021741511251713000227520ustar00rootroot00000000000000import { configure, mount } from 'enzyme'; import Adapter from 'enzyme-adapter-react-16'; import * as React from 'react'; import { sidecar } from 'use-sidecar'; import { RemoveScroll } from '../src/UI'; configure({ adapter: new Adapter() }); const tick = () => new Promise((resolve) => setTimeout(resolve, 10)); const car = sidecar(() => import('../src/sidecar')); describe('UI', () => { it('smoke', async () => { const wrapper = mount(content); await tick(); expect(wrapper.html()).toBe('
content
'); }); it('smoke as style class', async () => { const wrapper = mount( content ); await tick(); expect(wrapper.html()).toBe('content'); }); it('forward', async () => { const wrapper = mount( content ); await tick(); expect(wrapper.html()).toBe('content'); }); }); theKashey-react-remove-scroll-b5d57a4/__tests__/combination.tsx000066400000000000000000000023351511251713000247360ustar00rootroot00000000000000import { configure, mount } from 'enzyme'; import Adapter from 'enzyme-adapter-react-16'; import * as React from 'react'; import { RemoveScroll } from '../src'; configure({ adapter: new Adapter() }); const tick = () => new Promise((resolve) => setTimeout(resolve, 10)); describe('Endpoint UI', () => { it('smoke', async () => { const wrapper = mount(content); expect(wrapper.html()).toContain('content'); await tick(); expect(wrapper.html()).toContain('content'); expect(document.body.className).toBe(''); }); it('smoke', async () => { const wrapper = mount(content); expect(wrapper.html()).toContain('content'); await tick(); expect(wrapper.html()).toContain('content'); expect(document.body.className).toBe('block-interactivity-2'); wrapper.unmount(); expect(document.body.className).toBe(''); }); it('forward', async () => { const wrapper = mount(
content
); expect(wrapper.html()).toContain('content'); await tick(); expect(wrapper.html()).toContain('content'); expect(document.body.className).toBe(''); }); }); theKashey-react-remove-scroll-b5d57a4/example/000077500000000000000000000000001511251713000213665ustar00rootroot00000000000000theKashey-react-remove-scroll-b5d57a4/example/app.tsx000066400000000000000000000057531511251713000227200ustar00rootroot00000000000000import * as React from 'react'; import * as ReactDOM from 'react-dom'; import {Component} from 'react'; import {RemoveScroll} from "../src/UI"; import {sidecar} from "use-sidecar"; const lockSideCar = sidecar(() => import ("../src/sidecar")); export interface AppState { counter: number; } const fill = (x: number, y: number) => { const a: number[] = []; for (let i = 0; i < x; ++i) { a.push(y) } return a; } const PDiv = () => (
PORTALED SCROLLABLE {fill(20, 1).map(x =>

{x}****

)}
); const Portal = () => ( ReactDOM.createPortal(, document.getElementById('portal')!) ) export default class App extends Component <{}, AppState> { state: AppState = { counter: 0 }; componentDidMount() { setInterval(() => { //this.setState({counter: this.state.counter ? 0 : 1}) }, 1000); setTimeout(() => { //this.setState({counter: this.state.counter ? 0 : 1}) }, 1000); } render() { return (
floating
SCROLL (end of content would be hidden under "parent" scroll). {(
PRIMARY SCROLLABLE YY ZZZ AAAA {fill(10, 1).map(x =>

{x} --****--

)} AAAA ZZZ YY
)} SCROLL

SCROLL

SCROLL

FILLER (not scrollable)

{fill(100, 1).map((_, index) =>

{index}****

)}

END

) } }theKashey-react-remove-scroll-b5d57a4/example/assets/000077500000000000000000000000001511251713000226705ustar00rootroot00000000000000theKashey-react-remove-scroll-b5d57a4/example/assets/.gitkeep000066400000000000000000000000001511251713000243070ustar00rootroot00000000000000theKashey-react-remove-scroll-b5d57a4/example/index.html000066400000000000000000000005631511251713000233670ustar00rootroot00000000000000 Example
theKashey-react-remove-scroll-b5d57a4/example/index.tsx000066400000000000000000000003701511251713000232350ustar00rootroot00000000000000import * as React from 'react'; import * as ReactDOM from 'react-dom'; import App from './app'; import XYBox from './xyScroll'; //ReactDOM.render(, document.getElementById('app')); ReactDOM.render(, document.getElementById('app')); theKashey-react-remove-scroll-b5d57a4/example/styles.css000066400000000000000000000016621511251713000234300ustar00rootroot00000000000000.App { font-family: sans-serif; text-align: center; width: 1024px; height: 1024px; overflow: scroll; -webkit-overflow-scrolling: touch; } .Sub { width: 300px; height: 300px; border: 1px solid #000; overflow: auto; } .SubSub { width: 200px; height: 200px; border: 1px solid #000; overflow: auto; overflow-y: auto; } .container { background-color: #e8eaf6; width: 600px; height: 200px; /*overflow: scroll;*/ -webkit-overflow-scrolling: touch; } .container .flex-container { list-style: none; padding: 0; margin: 12px; display: flex; /*flex-direction: column;*/ } .container .flex-container .flex-item { background-color: #c5cae9; width: 150px; height: 100px; display: flex; justify-content: center; align-items: center; } .container .flex-container .flex-item.flex-item:not(:last-of-type) { margin-right: 12px; } theKashey-react-remove-scroll-b5d57a4/example/utils.ts000066400000000000000000000006401511251713000230760ustar00rootroot00000000000000import {Component} from 'react'; export class ToolboxApp extends Component { onCheckboxChange = (propName: any) => () => { const currentValue = (this.state as any)[propName]; this.setState({ [propName]: !currentValue } as any); } onFieldTextChange = (propName: any) => (e: any) => { const value = e.target.value; (this as any).setState({ [propName]: value }); } }theKashey-react-remove-scroll-b5d57a4/example/xyScroll.tsx000066400000000000000000000035421511251713000237510ustar00rootroot00000000000000import * as React from "react"; import {RemoveScroll} from "../src"; import "style-loader!css-loader!./styles.css"; export default function XYBox() { return (
  • *1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • *1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
{/*
*/} {/*
    */} {/*
  • *1
  • */} {/*
  • 2
  • */} {/*
  • 3
  • */} {/*
  • 4
  • */} {/*
  • 5
  • */} {/*
  • 6
  • */} {/*
  • 7
  • */} {/*
  • 8
  • */} {/*
*/} {/*
*/}
); } theKashey-react-remove-scroll-b5d57a4/jest.config.js000066400000000000000000000000531511251713000225000ustar00rootroot00000000000000module.exports = { preset: 'ts-jest', }; theKashey-react-remove-scroll-b5d57a4/package.json000066400000000000000000000047441511251713000222320ustar00rootroot00000000000000{ "name": "react-remove-scroll", "version": "2.7.2", "description": "Disables scroll outside of `children` node.", "main": "dist/es5/index.js", "jsnext:main": "dist/es2015/index.js", "module": "dist/es2015/index.js", "types": "dist/es5/index.d.ts", "module:es2019": "dist/es2019/index.js", "scripts": { "dev": "lib-builder dev", "test": "jest", "test:ci": "jest --runInBand --coverage", "build": "lib-builder build && yarn size:report", "release": "yarn build && yarn test", "size": "size-limit", "size:report": "size-limit --json > .size.json", "lint": "lib-builder lint", "format": "lib-builder format", "update": "lib-builder update", "prepublish": "yarn build && yarn changelog", "changelog": "conventional-changelog -p angular -i CHANGELOG.md -s", "changelog:rewrite": "conventional-changelog -p angular -i CHANGELOG.md -s -r 0", "storybook": "start-storybook -p 6006" }, "keywords": [ "scroll" ], "author": "Anton Korzunov ", "license": "MIT", "devDependencies": { "@types/react": "^18.0.0", "@babel/core": "^7.17.9", "@size-limit/preset-small-lib": "^11.0.2", "size-limit": "^11.0.2", "@storybook/react": "^6.4.22", "@theuiteam/lib-builder": "^0.1.4", "@types/enzyme-adapter-react-16": "^1.0.6", "babel-loader": "^8.2.4", "enzyme-adapter-react-16": "^1.15.6" }, "resolutions": { "@types/react": "^18.0.0", "tslib": "^2.1.0" }, "engines": { "node": ">=10" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" }, "peerDependenciesMeta": { "@types/react": { "optional": true } }, "files": [ "dist", "UI", "sidecar" ], "repository": "https://github.com/theKashey/react-remove-scroll", "dependencies": { "react-remove-scroll-bar": "^2.3.7", "react-style-singleton": "^2.2.3", "tslib": "^2.1.0", "use-callback-ref": "^1.3.3", "use-sidecar": "^1.1.3" }, "sideEffects": [ "**/sidecar.js" ], "husky": { "hooks": { "pre-commit": "lint-staged" } }, "lint-staged": { "*.{ts,tsx}": [ "prettier --write", "eslint --fix", "git add" ], "*.{js,css,json,md}": [ "prettier --write", "git add" ] }, "prettier": { "printWidth": 120, "trailingComma": "es5", "tabWidth": 2, "semi": true, "singleQuote": true }, "packageManager": "yarn@1.22.19" } theKashey-react-remove-scroll-b5d57a4/sidecar/000077500000000000000000000000001511251713000213455ustar00rootroot00000000000000theKashey-react-remove-scroll-b5d57a4/sidecar/package.json000066400000000000000000000002541511251713000236340ustar00rootroot00000000000000{ "private": true, "main": "../dist/es5/sidecar.js", "jsnext:main": "../dist/es2015/sidecar.js", "module": "../dist/es2015/sidecar.js", "types": "sidecar.d.ts" } theKashey-react-remove-scroll-b5d57a4/sidecar/sidecar.d.ts000066400000000000000000000001311511251713000235440ustar00rootroot00000000000000import * as React from 'react'; declare let sidecar: React.FC; export default sidecar; theKashey-react-remove-scroll-b5d57a4/src/000077500000000000000000000000001511251713000205225ustar00rootroot00000000000000theKashey-react-remove-scroll-b5d57a4/src/Combination.tsx000066400000000000000000000006711511251713000235300ustar00rootroot00000000000000import * as React from 'react'; import { RemoveScroll } from './UI'; import SideCar from './sidecar'; import { IRemoveScrollProps, RemoveScrollType } from './types'; const ReactRemoveScroll: RemoveScrollType = React.forwardRef((props, ref) => ( )) as any; ReactRemoveScroll.classNames = RemoveScroll.classNames; export default ReactRemoveScroll; theKashey-react-remove-scroll-b5d57a4/src/SideEffect.tsx000066400000000000000000000171261511251713000232720ustar00rootroot00000000000000import * as React from 'react'; import { TouchEvent } from 'react'; import { RemoveScrollBar } from 'react-remove-scroll-bar'; import { styleSingleton } from 'react-style-singleton'; import { nonPassive } from './aggresiveCapture'; import { handleScroll, locationCouldBeScrolled } from './handleScroll'; import { Axis, IRemoveScrollEffectProps } from './types'; export const getTouchXY = (event: TouchEvent | WheelEvent) => 'changedTouches' in event ? [event.changedTouches[0].clientX, event.changedTouches[0].clientY] : [0, 0]; export const getDeltaXY = (event: WheelEvent) => [event.deltaX, event.deltaY]; const extractRef = (ref: React.RefObject | HTMLElement): HTMLElement => ref && 'current' in ref ? ref.current : ref; const deltaCompare = (x: number[], y: number[]) => x[0] === y[0] && x[1] === y[1]; const generateStyle = (id: number) => ` .block-interactivity-${id} {pointer-events: none;} .allow-interactivity-${id} {pointer-events: all;} `; let idCounter = 0; let lockStack: any[] = []; export function RemoveScrollSideCar(props: IRemoveScrollEffectProps) { const shouldPreventQueue = React.useRef>([]); const touchStartRef = React.useRef([0, 0]); const activeAxis = React.useRef(); const [id] = React.useState(idCounter++); const [Style] = React.useState(styleSingleton); const lastProps = React.useRef(props); React.useEffect(() => { lastProps.current = props; }, [props]); React.useEffect(() => { if (props.inert) { document.body.classList.add(`block-interactivity-${id}`); const allow = [props.lockRef.current, ...(props.shards || []).map(extractRef)].filter(Boolean); allow.forEach((el) => el!.classList.add(`allow-interactivity-${id}`)); return () => { document.body.classList.remove(`block-interactivity-${id}`); allow.forEach((el) => el!.classList.remove(`allow-interactivity-${id}`)); }; } return; }, [props.inert, props.lockRef.current, props.shards]); const shouldCancelEvent = React.useCallback((event: WheelEvent | TouchEvent, parent: HTMLElement) => { if (('touches' in event && event.touches.length === 2) || (event.type === 'wheel' && event.ctrlKey)) { return !lastProps.current.allowPinchZoom; } const touch = getTouchXY(event); const touchStart = touchStartRef.current; const deltaX = 'deltaX' in event ? event.deltaX : touchStart[0] - touch[0]; const deltaY = 'deltaY' in event ? event.deltaY : touchStart[1] - touch[1]; let currentAxis: Axis | undefined; const target: HTMLElement = event.target as any; const moveDirection: Axis = Math.abs(deltaX) > Math.abs(deltaY) ? 'h' : 'v'; // allow horizontal touch move on Range inputs. They will not cause any scroll if ('touches' in event && moveDirection === 'h' && (target as HTMLInputElement).type === 'range') { return false; } // allow drag selection (iOS); check if selection's anchorNode is the same as target or contains target const selection = window.getSelection(); const anchorNode = selection && selection.anchorNode; const isTouchingSelection = anchorNode ? anchorNode === target || anchorNode.contains(target) : false; if (isTouchingSelection) { return false; } let canBeScrolledInMainDirection = locationCouldBeScrolled(moveDirection, target); if (!canBeScrolledInMainDirection) { return true; } if (canBeScrolledInMainDirection) { currentAxis = moveDirection; } else { currentAxis = moveDirection === 'v' ? 'h' : 'v'; canBeScrolledInMainDirection = locationCouldBeScrolled(moveDirection, target); // other axis might be not scrollable } if (!canBeScrolledInMainDirection) { return false; } if (!activeAxis.current && 'changedTouches' in event && (deltaX || deltaY)) { activeAxis.current = currentAxis; } if (!currentAxis) { return true; } const cancelingAxis = activeAxis.current || currentAxis; return handleScroll(cancelingAxis, parent, event, cancelingAxis === 'h' ? deltaX : deltaY, true); }, []); const shouldPrevent = React.useCallback((_event: Event) => { const event: WheelEvent | TouchEvent = _event as any; if (!lockStack.length || lockStack[lockStack.length - 1] !== Style) { // not the last active return; } const delta = 'deltaY' in event ? getDeltaXY(event) : getTouchXY(event); const sourceEvent = shouldPreventQueue.current.filter( (e) => e.name === event.type && (e.target === event.target || event.target === e.shadowParent) && deltaCompare(e.delta, delta) )[0]; // self event, and should be canceled if (sourceEvent && sourceEvent.should) { if (event.cancelable) { event.preventDefault(); } return; } // outside or shard event if (!sourceEvent) { const shardNodes = (lastProps.current.shards || []) .map(extractRef) .filter(Boolean) .filter((node) => node.contains(event.target as any)); const shouldStop = shardNodes.length > 0 ? shouldCancelEvent(event, shardNodes[0]) : !lastProps.current.noIsolation; if (shouldStop) { if (event.cancelable) { event.preventDefault(); } } } }, []); const shouldCancel = React.useCallback((name: string, delta: number[], target: any, should: boolean) => { const event = { name, delta, target, should, shadowParent: getOutermostShadowParent(target) }; shouldPreventQueue.current.push(event); setTimeout(() => { shouldPreventQueue.current = shouldPreventQueue.current.filter((e) => e !== event); }, 1); }, []); const scrollTouchStart = React.useCallback((event: any) => { touchStartRef.current = getTouchXY(event); activeAxis.current = undefined; }, []); const scrollWheel = React.useCallback((event: WheelEvent) => { shouldCancel(event.type, getDeltaXY(event), event.target, shouldCancelEvent(event, props.lockRef.current as any)); }, []); const scrollTouchMove = React.useCallback((event: TouchEvent) => { shouldCancel(event.type, getTouchXY(event), event.target, shouldCancelEvent(event, props.lockRef.current as any)); }, []); React.useEffect(() => { lockStack.push(Style); props.setCallbacks({ onScrollCapture: scrollWheel, onWheelCapture: scrollWheel, onTouchMoveCapture: scrollTouchMove, }); document.addEventListener('wheel', shouldPrevent, nonPassive); document.addEventListener('touchmove', shouldPrevent, nonPassive); document.addEventListener('touchstart', scrollTouchStart, nonPassive); return () => { lockStack = lockStack.filter((inst) => inst !== Style); document.removeEventListener('wheel', shouldPrevent, nonPassive as any); document.removeEventListener('touchmove', shouldPrevent, nonPassive as any); document.removeEventListener('touchstart', scrollTouchStart, nonPassive as any); }; }, []); const { removeScrollBar, inert } = props; return ( {inert ?