├── .devcontainer └── devcontainer.json ├── .gitattributes ├── .github ├── FUNDING.yml ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md ├── codecov.yml └── workflows │ └── test.yml ├── .gitignore ├── .npmrc ├── .prettierignore ├── .prettierrc ├── LICENSE ├── README.md ├── docs ├── .nojekyll ├── 404.html ├── _next │ └── static │ │ ├── GxYfIvv4skn0SeOkDcZyD │ │ ├── _buildManifest.js │ │ └── _ssgManifest.js │ │ ├── chunks │ │ ├── 23-503bf6f9a94b3b03.js │ │ ├── 231-d4aaea19b054ec1b.js │ │ ├── 808-f49c71865180a278.js │ │ ├── 88-9d55cab378812048.js │ │ ├── app │ │ │ ├── _not-found │ │ │ │ └── page-37de0708a55a06c5.js │ │ │ ├── examples │ │ │ │ └── page-5854916217ce4b07.js │ │ │ ├── layout-4471d03b3bb2b863.js │ │ │ └── page-e71d09868f648c16.js │ │ ├── fd9d1056-6184565b3c21c232.js │ │ ├── framework-aec844d2ccbe7592.js │ │ ├── main-84e765bff17cc101.js │ │ ├── main-app-e16a37cf1e78b3fe.js │ │ ├── pages │ │ │ ├── _app-6a626577ffa902a4.js │ │ │ └── _error-1be831200e60c5c0.js │ │ ├── polyfills-78c92fac7aa8fdd8.js │ │ └── webpack-be770bf02301ed46.js │ │ └── css │ │ └── 178f3b670fe3922d.css ├── example │ ├── angular │ │ ├── 3rdpartylicenses.txt │ │ ├── assets │ │ │ └── logo.svg │ │ ├── index.html │ │ ├── main.2c174d9758291a62.js │ │ ├── polyfills.9034b76fad7184d7.js │ │ ├── runtime.a8f964f4849dbf7a.js │ │ └── styles.0904b1cd2173caf4.css │ ├── overlayscrollbars │ │ ├── assets │ │ │ ├── index-BmJ6F1g4.css │ │ │ └── index-BqZqzbcy.js │ │ ├── favicon.ico │ │ ├── index.html │ │ └── logo.png │ ├── react │ │ ├── assets │ │ │ ├── index-C3_quvdF.js │ │ │ └── index-Cb2ahZ1Z.css │ │ ├── index.html │ │ └── logo.svg │ ├── solid │ │ ├── assets │ │ │ ├── index-D-YHenZk.css │ │ │ └── index-YuypYTvl.js │ │ ├── index.html │ │ └── logo.svg │ ├── svelte │ │ ├── assets │ │ │ ├── index-DYQr1_g2.js │ │ │ └── index-l1pS4JDj.css │ │ ├── index.html │ │ └── logo.svg │ └── vue │ │ ├── assets │ │ ├── index-CvpB9SWZ.js │ │ └── index-GKMmJ_7s.css │ │ ├── index.html │ │ └── logo.svg ├── examples.html ├── examples.txt ├── favicon.ico ├── font │ └── inter │ │ ├── inter-variable-slnt-wght.ttf │ │ └── inter-variable-slnt-wght.woff2 ├── google687f0387fb3e7e4e.html ├── icon │ ├── github.svg │ └── javascript.svg ├── img │ ├── adminlte-logo.png │ ├── browserstack.png │ ├── intellij-idea-logo.svg │ ├── logo.svg │ ├── scramble-logo.svg │ ├── spotify-logo.svg │ └── storybook-logo.svg ├── index.html ├── index.txt └── v1 │ ├── .pleeeaserc │ ├── _framework │ ├── css │ │ ├── OverlayScrollbars.css │ │ └── OverlayScrollbars.min.css │ ├── fonts │ │ ├── materialdesignicons-webfont.eot │ │ ├── materialdesignicons-webfont.ttf │ │ ├── materialdesignicons-webfont.woff │ │ └── materialdesignicons-webfont.woff2 │ ├── html │ │ └── 404.html │ ├── img │ │ └── icons-browser │ │ │ ├── chrome.svg │ │ │ ├── edge.svg │ │ │ ├── firefox.svg │ │ │ ├── ie.svg │ │ │ ├── opera.svg │ │ │ └── safari.svg │ ├── js │ │ ├── OverlayScrollbars.js │ │ ├── OverlayScrollbars.min.js │ │ ├── framework.js │ │ ├── jquery.overlayScrollbars.js │ │ └── jquery.overlayScrollbars.min.js │ ├── plugins │ │ ├── css │ │ │ ├── codemirror │ │ │ │ └── codemirror.css │ │ │ ├── highlightjs │ │ │ │ └── sora.css │ │ │ ├── jquery.modal │ │ │ │ └── jquery.modal.css │ │ │ └── tippy │ │ │ │ └── tippy.css │ │ └── js │ │ │ ├── codemirror │ │ │ ├── codemirror.min.js │ │ │ └── mode │ │ │ │ └── javascript.min.js │ │ │ ├── day.min.js │ │ │ ├── hasher.min.js │ │ │ ├── highlight.min.js │ │ │ ├── jquery.easing.js │ │ │ ├── jquery.min.js │ │ │ ├── jquery.raf.min.js │ │ │ ├── signals.min.js │ │ │ ├── tippy.min.js │ │ │ └── viewport-units-buggyfill.min.js │ └── scss │ │ ├── 3rd │ │ ├── _animated.scss │ │ ├── _core.scss │ │ ├── _extras.scss │ │ ├── _functions.scss │ │ ├── _icons.scss │ │ ├── _path.scss │ │ ├── _variables.scss │ │ ├── materialdesignicons.scss │ │ ├── normalize.css.map │ │ └── normalize.scss │ │ └── base.scss │ ├── design │ ├── _old │ │ ├── logo.ai │ │ └── logo.png │ ├── favicon.png │ ├── favicon.psd │ ├── logo.ai │ ├── logo.png │ ├── logo.svg │ └── logo_backup.ai │ ├── etc │ ├── iframe.html │ ├── os-theme-block-dark.css │ ├── os-theme-block-light.css │ ├── os-theme-minimal-dark.css │ ├── os-theme-minimal-light.css │ ├── os-theme-round-dark.css │ ├── os-theme-round-light.css │ ├── os-theme-thick-dark.css │ ├── os-theme-thick-light.css │ ├── os-theme-thin-dark.css │ └── os-theme-thin-light.css │ ├── favicon.ico │ ├── frameworks │ ├── angular │ │ ├── 3rdpartylicenses.txt │ │ ├── angular.1effc66e349b0834b6d4.svg │ │ ├── assets │ │ │ ├── angular.svg │ │ │ └── overlayscrollbars.svg │ │ ├── favicon.ico │ │ ├── index.html │ │ ├── logo.svg │ │ ├── main.3d4d4af62ba8f204a808.js │ │ ├── overlayscrollbars.7f1a49176e639b732f4e.svg │ │ ├── polyfills.8c151b8375e767ff858f.js │ │ ├── runtime.0e49e2b53282f40c8925.js │ │ └── styles.7aed20486ed751368dd7.css │ ├── react │ │ ├── asset-manifest.json │ │ ├── favicon.ico │ │ ├── index.html │ │ ├── logo.svg │ │ ├── manifest.json │ │ ├── precache-manifest.38429c8b057febf1cddfa242e6480d10.js │ │ ├── service-worker.js │ │ └── static │ │ │ ├── css │ │ │ ├── 2.cc8fcf68.chunk.css │ │ │ ├── 2.cc8fcf68.chunk.css.map │ │ │ ├── main.60b309a2.chunk.css │ │ │ ├── main.60b309a2.chunk.css.map │ │ │ ├── main.957e9a21.chunk.css │ │ │ └── main.957e9a21.chunk.css.map │ │ │ ├── js │ │ │ ├── 2.5462f35b.chunk.js │ │ │ ├── 2.5462f35b.chunk.js.map │ │ │ ├── 2.f58e91b4.chunk.js │ │ │ ├── 2.f58e91b4.chunk.js.map │ │ │ ├── main.1f7f80a4.chunk.js │ │ │ ├── main.1f7f80a4.chunk.js.map │ │ │ ├── main.3f7dc168.chunk.js │ │ │ ├── main.3f7dc168.chunk.js.map │ │ │ ├── runtime~main.6aaf21d4.js │ │ │ └── runtime~main.6aaf21d4.js.map │ │ │ └── media │ │ │ ├── overlayscrollbars.5075f690.svg │ │ │ ├── overlayscrollbars.bbebeed8.svg │ │ │ ├── react.7844928c.svg │ │ │ └── react.ba7f2cdb.svg │ └── vue │ │ ├── assets │ │ ├── index.61eee815.css │ │ ├── index.ba7f6fbf.css │ │ ├── index.d4c8b512.js │ │ ├── overlayscrollbars.8bc58976.svg │ │ └── vue.82507c49.svg │ │ ├── favicon.ico │ │ ├── index.html │ │ ├── js │ │ ├── app.e7d27ada.js │ │ ├── app.e7d27ada.js.map │ │ ├── chunk-vendors.6126fa6e.js │ │ └── chunk-vendors.6126fa6e.js.map │ │ └── logo.svg │ ├── google3e52b79b0ab45056.html │ ├── html │ ├── demos.html │ ├── documentation.html │ ├── extensions.html │ ├── faq.html │ ├── overview.html │ └── themes.html │ ├── img │ ├── browserstack.png │ ├── demo_content_annie.png │ ├── demo_content_connie.png │ ├── demo_content_eren.png │ ├── demo_content_erwin.png │ ├── demo_content_levi.png │ ├── demo_content_mikasa.png │ ├── demo_content_reiner.png │ └── demo_content_sasha.png │ ├── index.dev.html │ ├── index.dev.js │ ├── index.html │ ├── index.js │ ├── index.min.js │ ├── index.min.js.map │ ├── js │ ├── demos.js │ ├── documentation.js │ ├── extensions.js │ ├── faq.js │ ├── overview.js │ └── themes.js │ ├── pleeease--watch.bat │ ├── rollup-c.bat │ ├── rollup.config.js │ ├── sass--watch.bat │ ├── styles.min.css │ ├── styles.min.css.map │ ├── styles.scss │ └── variables.scss ├── eslint.config.js ├── examples ├── README.md ├── angular │ ├── .gitignore │ ├── angular.json │ ├── package-lock.json │ ├── package.json │ ├── src │ │ ├── app │ │ │ ├── app.component.ts │ │ │ ├── app.module.ts │ │ │ └── eventObserver.ts │ │ ├── assets │ │ │ └── logo.svg │ │ ├── index.html │ │ ├── main.ts │ │ ├── polyfills.ts │ │ └── styles.css │ ├── tsconfig.app.json │ └── tsconfig.json ├── browser │ ├── .gitignore │ ├── index.html │ ├── package-lock.json │ ├── package.json │ ├── public │ │ ├── favicon.ico │ │ └── logo.png │ ├── script.js │ ├── styles.css │ └── vite.config.js ├── node │ ├── .gitignore │ ├── index.html │ ├── package-lock.json │ ├── package.json │ ├── public │ │ ├── favicon.ico │ │ └── logo.png │ ├── src │ │ └── script.js │ ├── styles.css │ └── vite.config.js ├── overlayscrollbars │ ├── .gitignore │ ├── index.html │ ├── package-lock.json │ ├── package.json │ ├── public │ │ ├── favicon.ico │ │ └── logo.png │ ├── src │ │ ├── actions.ts │ │ ├── bodyOverlayScrollbars.ts │ │ ├── events.ts │ │ ├── index.ts │ │ └── vite-env.d.ts │ ├── styles.css │ ├── tsconfig.json │ └── vite.config.ts ├── react │ ├── .gitignore │ ├── index.html │ ├── package-lock.json │ ├── package.json │ ├── public │ │ └── logo.svg │ ├── src │ │ ├── App.tsx │ │ ├── index.css │ │ ├── main.tsx │ │ ├── useEventObserver.ts │ │ └── vite-env.d.ts │ ├── tsconfig.json │ ├── tsconfig.node.json │ └── vite.config.ts ├── solid │ ├── .gitignore │ ├── index.html │ ├── package-lock.json │ ├── package.json │ ├── public │ │ └── logo.svg │ ├── src │ │ ├── App.tsx │ │ ├── createEventObserver.ts │ │ ├── index.css │ │ └── index.tsx │ ├── tsconfig.json │ └── vite.config.ts ├── svelte │ ├── .gitignore │ ├── index.html │ ├── package-lock.json │ ├── package.json │ ├── public │ │ └── logo.svg │ ├── src │ │ ├── App.svelte │ │ ├── app.css │ │ ├── main.ts │ │ ├── useEventObserver.svelte.ts │ │ └── vite-env.d.ts │ ├── svelte.config.js │ ├── tsconfig.json │ ├── tsconfig.node.json │ └── vite.config.ts └── vue │ ├── .gitignore │ ├── env.d.ts │ ├── index.html │ ├── package-lock.json │ ├── package.json │ ├── public │ └── logo.svg │ ├── src │ ├── App.vue │ ├── main.css │ ├── main.ts │ └── useEventObserver.ts │ ├── tsconfig.config.json │ ├── tsconfig.json │ └── vite.config.ts ├── local ├── browser-testing │ ├── .gitignore │ ├── package.json │ ├── src │ │ ├── index.ts │ │ ├── resize.ts │ │ ├── select.ts │ │ ├── testResult.ts │ │ └── timeout.ts │ └── tsconfig.json ├── config │ ├── package.json │ └── src │ │ ├── full-coverage.js │ │ ├── mocks.js │ │ ├── playwright-coverage.js │ │ ├── playwright.js │ │ ├── resolve.json │ │ ├── vitest-coverage.js │ │ ├── vitest-setup.dom.js │ │ ├── vitest-setup.node.js │ │ └── vitest.js ├── esbuild │ ├── package.json │ └── src │ │ ├── esbuild.js │ │ ├── normalizePathSlashes.js │ │ ├── plugins │ │ ├── clearOldBuild.js │ │ ├── external.js │ │ ├── styles.js │ │ └── tailwind.js │ │ ├── resolveConfig.js │ │ └── writeOnlyChanges.js ├── full-coverage │ ├── bin │ │ └── generateFullCoverage.js │ └── package.json ├── playwright-tooling │ ├── bin │ │ └── mergeCoverage.js │ ├── index.d.ts │ ├── package-lock.json │ ├── package.json │ └── src │ │ ├── collectCoverage.js │ │ ├── expectSuccess.js │ │ ├── index.js │ │ ├── playwrightRollup.js │ │ └── rollup │ │ ├── rollupPlaywrightAdditionalWatchFilesPlugin.js │ │ ├── rollupPlaywrightConfig.js │ │ ├── rollupPlaywrightHtmlPlugin.js │ │ └── rollupPlaywrightIstanbulPlugin.js ├── rollup │ ├── package-lock.json │ ├── package.json │ └── src │ │ ├── bundle │ │ ├── babel.config.es2015.js │ │ ├── babel.config.es5.js │ │ ├── plugins.js │ │ ├── pre.js │ │ ├── script.default.js │ │ ├── script.esbuild.js │ │ ├── styles.js │ │ └── types.js │ │ ├── createRollupConfig.js │ │ ├── defaultOptions.js │ │ ├── pipeline.default.js │ │ └── plugins │ │ ├── rollupAdditionalWatchFilesPlugin.js │ │ ├── rollupCleanPlugin.js │ │ ├── rollupCopyPlugin.js │ │ ├── rollupEsbuildPlugin.js │ │ └── rollupPackageJsonPlugin.js ├── tailwind │ ├── package.json │ └── tailwind.config.js └── tsconfig │ ├── package.json │ └── tsconfig.json ├── logo ├── logo.ai ├── logo.png └── logo.svg ├── package-lock.json ├── package.json ├── packages ├── overlayscrollbars-ngx │ ├── .gitignore │ ├── CHANGELOG.md │ ├── README.md │ ├── angular.json │ ├── karma.conf.js │ ├── logo.svg │ ├── ng-package.json │ ├── package.json │ ├── src │ │ ├── overlayscrollbars.component.ts │ │ ├── overlayscrollbars.directive.ts │ │ ├── overlayscrollbars.module.ts │ │ └── public-api.ts │ ├── test │ │ ├── overlayscrollbars.component.spec.ts │ │ └── test.ts │ ├── tsconfig.json │ ├── tsconfig.lib.json │ ├── tsconfig.lib.prod.json │ └── tsconfig.spec.json ├── overlayscrollbars-react │ ├── .gitignore │ ├── CHANGELOG.md │ ├── README.md │ ├── logo.svg │ ├── package.json │ ├── src │ │ ├── OverlayScrollbarsComponent.tsx │ │ ├── overlayscrollbars-react.cts │ │ ├── overlayscrollbars-react.mts │ │ ├── overlayscrollbars-react.ts │ │ └── useOverlayScrollbars.ts │ ├── test │ │ ├── dom │ │ │ ├── OverlayScrollbarsComponent.test.tsx │ │ │ └── useOverlayScrollbars.test.tsx │ │ └── tsconfig.json │ ├── tsconfig.json │ ├── tsconfig.types.json │ ├── vite.config.js │ └── vitest.config.js ├── overlayscrollbars-solid │ ├── .gitignore │ ├── CHANGELOG.md │ ├── README.md │ ├── logo.svg │ ├── package.json │ ├── src │ │ ├── OverlayScrollbarsComponent.tsx │ │ ├── createOverlayScrollbars.ts │ │ ├── overlayscrollbars-solid.cts │ │ ├── overlayscrollbars-solid.mts │ │ └── overlayscrollbars-solid.ts │ ├── test │ │ ├── dom │ │ │ ├── OverlayScrollbarsComponent.test.tsx │ │ │ └── createOverlayScrollbars.test.tsx │ │ └── tsconfig.json │ ├── tsconfig.json │ ├── vite.config.js │ └── vitest.config.js ├── overlayscrollbars-svelte │ ├── .gitignore │ ├── CHANGELOG.md │ ├── README.md │ ├── env.d.ts │ ├── logo.svg │ ├── package.json │ ├── src │ │ ├── OverlayScrollbarsComponent.svelte │ │ ├── OverlayScrollbarsComponent.types.ts │ │ ├── overlayscrollbars-svelte.cts │ │ ├── overlayscrollbars-svelte.mts │ │ ├── overlayscrollbars-svelte.ts │ │ └── useOverlayScrollbars.svelte.ts │ ├── svelte.config.js │ ├── test │ │ ├── dom │ │ │ ├── OverlayScrollbarsComponent.test.ts │ │ │ ├── TestComponent.svelte │ │ │ ├── TestComponentBody.svelte │ │ │ ├── TestElement.svelte │ │ │ ├── TestUseOverlayScrollbarsInitialize.svelte │ │ │ └── useOverlayScrollbars.test.ts │ │ └── tsconfig.json │ ├── tsconfig.json │ ├── vite.config.js │ └── vitest.config.js ├── overlayscrollbars-vue │ ├── .gitignore │ ├── CHANGELOG.md │ ├── README.md │ ├── env.d.ts │ ├── logo.svg │ ├── package.json │ ├── src │ │ ├── OverlayScrollbarsComponent.types.ts │ │ ├── OverlayScrollbarsComponent.vue │ │ ├── overlayscrollbars-vue.cts │ │ ├── overlayscrollbars-vue.mts │ │ ├── overlayscrollbars-vue.ts │ │ └── useOverlayScrollbars.ts │ ├── test │ │ ├── dom │ │ │ ├── OverlayScrollbarsComponent.test.tsx │ │ │ └── useOverlayScrollbars.test.tsx │ │ └── tsconfig.json │ ├── tsconfig.json │ ├── tsconfig.types.json │ ├── vite.config.js │ └── vitest.config.js └── overlayscrollbars │ ├── .gitignore │ ├── CHANGELOG.md │ ├── README.md │ ├── globals.d.ts │ ├── package.json │ ├── playwright.config.js │ ├── rollup.config.js │ ├── src │ ├── classnames.ts │ ├── environment.ts │ ├── eventListeners.ts │ ├── index.scss │ ├── index.ts │ ├── initialization.ts │ ├── instances.ts │ ├── nonce.ts │ ├── observers │ │ ├── domObserver.ts │ │ ├── index.ts │ │ ├── sizeObserver.ts │ │ └── trinsicObserver.ts │ ├── options.ts │ ├── overlayscrollbars.ts │ ├── plugins │ │ ├── clickScrollPlugin │ │ │ ├── clickScrollPlugin.ts │ │ │ └── index.ts │ │ ├── index.ts │ │ ├── optionsValidationPlugin │ │ │ ├── index.ts │ │ │ ├── optionsValidationPlugin.ts │ │ │ ├── transformation.ts │ │ │ └── validation.ts │ │ ├── plugins.ts │ │ ├── scrollbarsHidingPlugin │ │ │ ├── index.ts │ │ │ └── scrollbarsHidingPlugin.ts │ │ └── sizeObserverPlugin │ │ │ ├── index.ts │ │ │ └── sizeObserverPlugin.ts │ ├── setups │ │ ├── index.ts │ │ ├── observersSetup │ │ │ ├── index.ts │ │ │ └── observersSetup.ts │ │ ├── scrollbarsSetup │ │ │ ├── index.ts │ │ │ ├── scrollbarsSetup.elements.ts │ │ │ ├── scrollbarsSetup.events.ts │ │ │ └── scrollbarsSetup.ts │ │ ├── setups.ts │ │ └── structureSetup │ │ │ ├── index.ts │ │ │ ├── structureSetup.elements.ts │ │ │ ├── structureSetup.ts │ │ │ ├── structureSetup.utils.ts │ │ │ └── updateSegments │ │ │ ├── index.ts │ │ │ ├── overflowUpdateSegment.ts │ │ │ ├── paddingUpdateSegment.ts │ │ │ └── trinsicUpdateSegment.ts │ ├── styles │ │ ├── scrollbars.scss │ │ ├── sizeobserver.scss │ │ ├── structure.scss │ │ ├── themes.scss │ │ └── trinsicobserver.scss │ ├── support │ │ ├── cache.ts │ │ ├── compatibility │ │ │ ├── apis.ts │ │ │ ├── index.ts │ │ │ └── isBrowser.ts │ │ ├── dom │ │ │ ├── attribute.ts │ │ │ ├── class.ts │ │ │ ├── create.ts │ │ │ ├── dimensions.ts │ │ │ ├── events.ts │ │ │ ├── focus.ts │ │ │ ├── index.ts │ │ │ ├── manipulation.ts │ │ │ ├── offset.ts │ │ │ ├── scroll.ts │ │ │ ├── style.ts │ │ │ ├── traversal.ts │ │ │ └── types.ts │ │ ├── eventListeners.ts │ │ ├── index.ts │ │ └── utils │ │ │ ├── alias.ts │ │ │ ├── animation.ts │ │ │ ├── array.ts │ │ │ ├── equal.ts │ │ │ ├── function.ts │ │ │ ├── index.ts │ │ │ ├── math.ts │ │ │ ├── noop.ts │ │ │ ├── object.ts │ │ │ ├── strings.ts │ │ │ └── types.ts │ ├── trustedTypePolicy.ts │ └── typings.ts │ ├── test │ ├── dom │ │ ├── environment.test.ts │ │ ├── initialization.test.ts │ │ ├── instances.test.ts │ │ ├── nonce.test.ts │ │ ├── observers │ │ │ ├── domObserver.test.ts │ │ │ ├── sizeObserver.test.ts │ │ │ └── trinsicObserver.test.ts │ │ ├── options.test.ts │ │ ├── overlayscrollbars.test.ts │ │ ├── plugins │ │ │ ├── optionsValidation │ │ │ │ ├── optionsValidation.test.ts │ │ │ │ ├── transformation.test.ts │ │ │ │ └── validation.test.ts │ │ │ └── plugins.test.ts │ │ ├── setups │ │ │ ├── scrollbarsSetup │ │ │ │ └── scrollbarsSetup.elements.test.ts │ │ │ └── structureSetup │ │ │ │ └── structureSetup.elements.test.ts │ │ ├── support │ │ │ ├── cache.test.ts │ │ │ ├── dom │ │ │ │ ├── attribute.test.ts │ │ │ │ ├── class.test.ts │ │ │ │ ├── create.test.ts │ │ │ │ ├── dimensions.test.ts │ │ │ │ ├── events.test.ts │ │ │ │ ├── manipulation.test.ts │ │ │ │ ├── offset.test.ts │ │ │ │ ├── scroll.test.ts │ │ │ │ ├── style.test.ts │ │ │ │ └── traversal.test.ts │ │ │ ├── eventListeners.test.ts │ │ │ └── utils │ │ │ │ ├── animation.test.ts │ │ │ │ ├── arrays.test.ts │ │ │ │ ├── equal.test.ts │ │ │ │ ├── function.test.ts │ │ │ │ ├── math.test.ts │ │ │ │ ├── object.test.ts │ │ │ │ ├── strings.test.ts │ │ │ │ └── types.test.ts │ │ └── trustedTypePolicy.test.ts │ ├── node │ │ ├── server.test.ts │ │ └── treeshaking.test.ts │ ├── package.json │ ├── playwright │ │ ├── appear │ │ │ ├── handleEnvironment.ts │ │ │ ├── index.browser.ts │ │ │ ├── index.html │ │ │ ├── index.scss │ │ │ └── index.test.ts │ │ ├── environment │ │ │ ├── index.browser.ts │ │ │ ├── index.html │ │ │ └── index.test.ts │ │ ├── observers │ │ │ ├── domObserver │ │ │ │ ├── index.browser.ts │ │ │ │ ├── index.html │ │ │ │ ├── index.scss │ │ │ │ └── index.test.ts │ │ │ ├── sizeObserver │ │ │ │ ├── handleEnvironment.ts │ │ │ │ ├── index.browser.ts │ │ │ │ ├── index.html │ │ │ │ ├── index.scss │ │ │ │ └── index.test.ts │ │ │ └── trinsicObserver │ │ │ │ ├── handleEnvironment.ts │ │ │ │ ├── index.browser.ts │ │ │ │ ├── index.html │ │ │ │ ├── index.scss │ │ │ │ └── index.test.ts │ │ ├── performance │ │ │ ├── fps │ │ │ │ ├── index.browser.ts │ │ │ │ ├── index.html │ │ │ │ ├── index.scss │ │ │ │ └── index.test.ts │ │ │ └── timing │ │ │ │ ├── handleEnvironment.ts │ │ │ │ ├── index.browser.ts │ │ │ │ ├── index.html │ │ │ │ ├── index.scss │ │ │ │ └── index.test.ts │ │ ├── scrollSnap │ │ │ ├── index.browser.ts │ │ │ ├── index.html │ │ │ ├── index.scss │ │ │ └── index.test.ts │ │ └── setups │ │ │ ├── scrollbarsSetup │ │ │ └── scrollbars │ │ │ │ ├── handleEnvironment.ts │ │ │ │ ├── index.browser.ts │ │ │ │ ├── index.html │ │ │ │ ├── index.scss │ │ │ │ └── index.test.ts │ │ │ └── structureSetup │ │ │ ├── body │ │ │ ├── handleEnvironment.ts │ │ │ ├── index.browser.ts │ │ │ ├── index.html │ │ │ ├── index.scss │ │ │ └── index.test.ts │ │ │ ├── focus │ │ │ ├── handleEnvironment.ts │ │ │ ├── index.browser.ts │ │ │ ├── index.html │ │ │ ├── index.scss │ │ │ └── index.test.ts │ │ │ ├── initScroll │ │ │ ├── handleEnvironment.ts │ │ │ ├── index.browser.ts │ │ │ ├── index.html │ │ │ ├── index.scss │ │ │ └── index.test.ts │ │ │ ├── nesting │ │ │ ├── index.browser.ts │ │ │ ├── index.html │ │ │ ├── index.scss │ │ │ └── index.test.ts │ │ │ └── update │ │ │ ├── handleEnvironment.ts │ │ │ ├── index.browser.ts │ │ │ ├── index.html │ │ │ ├── index.scss │ │ │ └── index.test.ts │ └── tsconfig.json │ ├── tsconfig.json │ ├── tsconfig.types.json │ └── vitest.config.js ├── tsconfig.json └── website ├── .gitignore ├── app ├── examples │ └── page.tsx ├── favicon.ico ├── layout.tsx ├── page.tsx └── styles.css ├── components ├── Html.tsx ├── Icon.tsx ├── Link.tsx ├── OverlayScrollbarsClientComponent.tsx ├── PageContainer.tsx └── google-ad.tsx ├── deploy.js ├── mdx-components.tsx ├── mdx ├── README.mdx └── components │ ├── Heading.tsx │ └── Pre.tsx ├── next.config.js ├── package-lock.json ├── package.json ├── postcss.config.js ├── public ├── font │ └── inter │ │ ├── inter-variable-slnt-wght.ttf │ │ └── inter-variable-slnt-wght.woff2 ├── icon │ ├── github.svg │ └── javascript.svg └── img │ ├── adminlte-logo.png │ ├── browserstack.png │ ├── intellij-idea-logo.svg │ ├── logo.svg │ ├── scramble-logo.svg │ ├── spotify-logo.svg │ └── storybook-logo.svg ├── tailwind.config.js └── tsconfig.json /.devcontainer/devcontainer.json: -------------------------------------------------------------------------------- 1 | // For format details, see https://aka.ms/devcontainer.json. For config options, see the 2 | // README at: https://github.com/devcontainers/templates/tree/main/src/typescript-node 3 | { 4 | "name": "Node.js & TypeScript", 5 | "image": "mcr.microsoft.com/devcontainers/typescript-node:20-bullseye" 6 | // "postCreateCommand": "npm i && npm run build:os" 7 | 8 | // Features to add to the dev container. More info: https://containers.dev/features. 9 | // "features": {}, 10 | 11 | // Use 'forwardPorts' to make a list of ports inside the container available locally. 12 | // "forwardPorts": [], 13 | 14 | // Configure tool-specific properties. 15 | // "customizations": {}, 16 | 17 | // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root. 18 | // "remoteUser": "root" 19 | } 20 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | website/** linguist-documentation -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: [KingSora] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | custom: ['https://www.paypal.me/ReneHaas'] # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 13 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help improve OverlayScrollbars 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | --- 8 | 9 | **Describe the bug** 10 | A clear and concise description of what the bug is. 11 | 12 | **To Reproduce** 13 | Steps to reproduce the behavior: 14 | 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Examples** 24 | Please create a minimal reproduction example of the bug. 25 | To do this you can use online platforms like https://stackblitz.com, https://jsfiddle.net or https://codesandbox.io. You can also create a separate Github repository which I can clone. 26 | 27 | As a starting point you could use one of the following templates: 28 | - Vanilla Javascript: https://stackblitz.com/edit/vitejs-vite-bv459t 29 | - React: https://stackblitz.com/edit/vitejs-vite-ou12p3 30 | - Vue: https://stackblitz.com/edit/vitejs-vite-8bbg5d 31 | 32 | **Environment** 33 | 34 | - OverlayScrollbars version: 35 | - Used Operating System(s): 36 | - Used Browser(s) (with version): 37 | 38 | **Additional context** 39 | Add any other context about the problem here. 40 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | --- 8 | 9 | **Is your feature request related to a problem? Please describe.** 10 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 11 | 12 | **Describe the solution you'd like** 13 | A clear and concise description of what you want to happen. 14 | 15 | **Describe alternatives you've considered** 16 | A clear and concise description of any alternative solutions or features you've considered. 17 | 18 | **Additional context** 19 | Add any other context or screenshots about the feature request here. 20 | -------------------------------------------------------------------------------- /.github/codecov.yml: -------------------------------------------------------------------------------- 1 | codecov: 2 | require_ci_to_pass: no 3 | notify: 4 | wait_for_ci: no 5 | 6 | coverage: 7 | status: 8 | project: off 9 | patch: off 10 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: Test 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | 8 | permissions: 9 | contents: read 10 | 11 | jobs: 12 | test: 13 | name: OverlayScrollbars Tests 14 | runs-on: ubuntu-latest 15 | steps: 16 | - name: Checkout Repo 17 | uses: actions/checkout@v3 18 | - name: Setup Node 19 | uses: actions/setup-node@v3 20 | with: 21 | node-version: '>=20.6.0' 22 | - name: Install dependencies 23 | run: npm ci 24 | - name: Build 25 | run: npm run build 26 | - name: Run Unit Tests 27 | run: npm run ci:test 28 | - name: Run e2e Tests 29 | run: xvfb-run npm run ci:e2e 30 | - name: Upload Unit Tests Coverage 31 | uses: codecov/codecov-action@v3 32 | with: 33 | flags: unit 34 | files: "packages/**/.coverage/unit/coverage*.json" 35 | - name: Upload e2e Tests Coverage 36 | uses: codecov/codecov-action@v3 37 | with: 38 | flags: e2e 39 | files: "packages/**/.coverage/e2e/coverage*.json" 40 | 41 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See http://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | node_modules/ 5 | 6 | # coverage 7 | .coverage/ 8 | 9 | # local env files 10 | .env.local 11 | .env.*.local 12 | 13 | # IDEs and editors 14 | /.idea 15 | .project 16 | .classpath 17 | .c9/ 18 | *.launch 19 | *.sublime-workspace 20 | .vscode/* 21 | !.vscode/settings.json 22 | !.vscode/tasks.json 23 | !.vscode/launch.json 24 | !.vscode/extensions.json 25 | .vscode 26 | 27 | # misc 28 | /.sass-cache 29 | npm-debug.log* 30 | yarn-debug.log* 31 | yarn-error.log* 32 | 33 | # System Files 34 | .DS_Store 35 | .env.local 36 | .env.development.local 37 | .env.test.local 38 | .env.production.local 39 | Thumbs.db 40 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | registry="https://registry.npmjs.org" -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | types 4 | .coverage 5 | .build 6 | .nyc_output -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 100, 3 | "tabWidth": 2, 4 | "singleQuote": true, 5 | "trailingComma": "es5", 6 | "arrowParens": "always", 7 | "endOfLine": "auto", 8 | "parser": "babel-ts", 9 | "overrides": [ 10 | { 11 | "files": "*.html", 12 | "options": { "parser": "html" } 13 | }, 14 | { 15 | "files": "*.css", 16 | "options": { "parser": "css" } 17 | }, 18 | { 19 | "files": "*.scss", 20 | "options": { "parser": "scss" } 21 | }, 22 | { 23 | "files": "*.vue", 24 | "options": { "parser": "vue" } 25 | }, 26 | { 27 | "files": "*.component.html", 28 | "options": { "parser": "angular" } 29 | }, 30 | { 31 | "files": ".prettierrc", 32 | "options": { "parser": "json" } 33 | } 34 | ] 35 | } 36 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Rene Haas 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /docs/.nojekyll: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /docs/_next/static/GxYfIvv4skn0SeOkDcZyD/_buildManifest.js: -------------------------------------------------------------------------------- 1 | self.__BUILD_MANIFEST={__rewrites:{afterFiles:[],beforeFiles:[],fallback:[]},"/_error":["static/chunks/pages/_error-1be831200e60c5c0.js"],sortedPages:["/_app","/_error"]},self.__BUILD_MANIFEST_CB&&self.__BUILD_MANIFEST_CB(); -------------------------------------------------------------------------------- /docs/_next/static/GxYfIvv4skn0SeOkDcZyD/_ssgManifest.js: -------------------------------------------------------------------------------- 1 | self.__SSG_MANIFEST=new Set([]);self.__SSG_MANIFEST_CB&&self.__SSG_MANIFEST_CB() -------------------------------------------------------------------------------- /docs/_next/static/chunks/app/examples/page-5854916217ce4b07.js: -------------------------------------------------------------------------------- 1 | (self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[668],{26:function(n,e,u){Promise.resolve().then(u.t.bind(u,231,23))}},function(n){n.O(0,[231,971,23,744],function(){return n(n.s=26)}),_N_E=n.O()}]); -------------------------------------------------------------------------------- /docs/_next/static/chunks/app/page-e71d09868f648c16.js: -------------------------------------------------------------------------------- 1 | (self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[931],{7201:function(n,e,r){Promise.resolve().then(r.bind(r,4344)),Promise.resolve().then(r.t.bind(r,231,23))},4344:function(n,e,r){"use strict";r.r(e),r.d(e,{OverlayScrollbarsClientComponent:function(){return t.E}});var t=r(8808)}},function(n){n.O(0,[231,808,971,23,744],function(){return n(n.s=7201)}),_N_E=n.O()}]); -------------------------------------------------------------------------------- /docs/_next/static/chunks/main-app-e16a37cf1e78b3fe.js: -------------------------------------------------------------------------------- 1 | (self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[744],{3964:function(e,n,t){Promise.resolve().then(t.t.bind(t,5751,23)),Promise.resolve().then(t.t.bind(t,6513,23)),Promise.resolve().then(t.t.bind(t,6130,23)),Promise.resolve().then(t.t.bind(t,9275,23)),Promise.resolve().then(t.t.bind(t,5324,23)),Promise.resolve().then(t.t.bind(t,1343,23))}},function(e){var n=function(n){return e(e.s=n)};e.O(0,[971,23],function(){return n(1028),n(3964)}),_N_E=e.O()}]); -------------------------------------------------------------------------------- /docs/_next/static/chunks/pages/_app-6a626577ffa902a4.js: -------------------------------------------------------------------------------- 1 | (self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[888],{1597:function(n,_,u){(window.__NEXT_P=window.__NEXT_P||[]).push(["/_app",function(){return u(2239)}])}},function(n){var _=function(_){return n(n.s=_)};n.O(0,[774,179],function(){return _(1597),_(6036)}),_N_E=n.O()}]); -------------------------------------------------------------------------------- /docs/_next/static/chunks/pages/_error-1be831200e60c5c0.js: -------------------------------------------------------------------------------- 1 | (self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[820],{1981:function(n,_,u){(window.__NEXT_P=window.__NEXT_P||[]).push(["/_error",function(){return u(3387)}])}},function(n){n.O(0,[888,774,179],function(){return n(n.s=1981)}),_N_E=n.O()}]); -------------------------------------------------------------------------------- /docs/example/angular/assets/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /docs/example/angular/runtime.a8f964f4849dbf7a.js: -------------------------------------------------------------------------------- 1 | (()=>{"use strict";var e,_={},p={};function n(e){var a=p[e];if(void 0!==a)return a.exports;var r=p[e]={exports:{}};return _[e](r,r.exports,n),r.exports}n.m=_,e=[],n.O=(a,r,u,l)=>{if(!r){var o=1/0;for(f=0;f=l)&&Object.keys(n.O).every(h=>n.O[h](r[t]))?r.splice(t--,1):(s=!1,l0&&e[f-1][2]>l;f--)e[f]=e[f-1];e[f]=[r,u,l]},n.n=e=>{var a=e&&e.__esModule?()=>e.default:()=>e;return n.d(a,{a}),a},n.d=(e,a)=>{for(var r in a)n.o(a,r)&&!n.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:a[r]})},n.o=(e,a)=>Object.prototype.hasOwnProperty.call(e,a),(()=>{var e={666:0};n.O.j=u=>0===e[u];var a=(u,l)=>{var t,c,[f,o,s]=l,v=0;if(f.some(d=>0!==e[d])){for(t in o)n.o(o,t)&&(n.m[t]=o[t]);if(s)var b=s(n)}for(u&&u(l);v 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 13 | OverlayScrollbars & React 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | -------------------------------------------------------------------------------- /docs/example/solid/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 13 | OverlayScrollbars & Solid 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | -------------------------------------------------------------------------------- /docs/example/svelte/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 14 | OverlayScrollbars & Svelte 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | -------------------------------------------------------------------------------- /docs/example/vue/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 13 | OverlayScrollbars & Vue 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | -------------------------------------------------------------------------------- /docs/example/vue/logo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KingSora/OverlayScrollbars/9cb3e2249f4be85e1e27753a85d20c00fc68cbda/docs/favicon.ico -------------------------------------------------------------------------------- /docs/font/inter/inter-variable-slnt-wght.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KingSora/OverlayScrollbars/9cb3e2249f4be85e1e27753a85d20c00fc68cbda/docs/font/inter/inter-variable-slnt-wght.ttf -------------------------------------------------------------------------------- /docs/font/inter/inter-variable-slnt-wght.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KingSora/OverlayScrollbars/9cb3e2249f4be85e1e27753a85d20c00fc68cbda/docs/font/inter/inter-variable-slnt-wght.woff2 -------------------------------------------------------------------------------- /docs/google687f0387fb3e7e4e.html: -------------------------------------------------------------------------------- 1 | google-site-verification: google687f0387fb3e7e4e.html -------------------------------------------------------------------------------- /docs/icon/github.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/icon/javascript.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /docs/img/adminlte-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KingSora/OverlayScrollbars/9cb3e2249f4be85e1e27753a85d20c00fc68cbda/docs/img/adminlte-logo.png -------------------------------------------------------------------------------- /docs/img/browserstack.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KingSora/OverlayScrollbars/9cb3e2249f4be85e1e27753a85d20c00fc68cbda/docs/img/browserstack.png -------------------------------------------------------------------------------- /docs/v1/.pleeeaserc: -------------------------------------------------------------------------------- 1 | { 2 | "in": "styles.scss", 3 | "out": "styles.min.css", 4 | "autoprefixer": {"browsers": [">0.5%", "iOS 6", "last 2 versions", "Firefox >= 20", "Firefox ESR"]}, 5 | "filters": false, 6 | "rem": false, 7 | "pseudoElements": true, 8 | "opacity": false, 9 | 10 | "import": false, 11 | "minifier": true, 12 | "mqpacker": false, 13 | 14 | "sass": true, 15 | "sourcemaps": { 16 | "map": { 17 | "inline": false 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /docs/v1/_framework/fonts/materialdesignicons-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KingSora/OverlayScrollbars/9cb3e2249f4be85e1e27753a85d20c00fc68cbda/docs/v1/_framework/fonts/materialdesignicons-webfont.eot -------------------------------------------------------------------------------- /docs/v1/_framework/fonts/materialdesignicons-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KingSora/OverlayScrollbars/9cb3e2249f4be85e1e27753a85d20c00fc68cbda/docs/v1/_framework/fonts/materialdesignicons-webfont.ttf -------------------------------------------------------------------------------- /docs/v1/_framework/fonts/materialdesignicons-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KingSora/OverlayScrollbars/9cb3e2249f4be85e1e27753a85d20c00fc68cbda/docs/v1/_framework/fonts/materialdesignicons-webfont.woff -------------------------------------------------------------------------------- /docs/v1/_framework/fonts/materialdesignicons-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KingSora/OverlayScrollbars/9cb3e2249f4be85e1e27753a85d20c00fc68cbda/docs/v1/_framework/fonts/materialdesignicons-webfont.woff2 -------------------------------------------------------------------------------- /docs/v1/_framework/html/404.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |

404

4 |

5 | The page you are looking for, couldn't be found! 6 |

7 |

8 |

9 |
10 |
11 | -------------------------------------------------------------------------------- /docs/v1/_framework/img/icons-browser/edge.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /docs/v1/_framework/plugins/js/jquery.raf.min.js: -------------------------------------------------------------------------------- 1 | /*! jQuery requestAnimationFrame - 0.2.3-pre - 2016-10-26 2 | * https://github.com/gnarf37/jquery-requestAnimationFrame 3 | * Copyright (c) 2016 Corey Frang; Licensed MIT */ 4 | !function(a){"function"==typeof define&&define.amd?define(["jquery"],a):a(jQuery)}(function(a){function b(){c&&(window.requestAnimationFrame(b),a.fx.tick())}if(Number(a.fn.jquery.split(".")[0])>=3)return void(window.console&&window.console.warn&&window.console.warn("The jquery.requestanimationframe plugin is not needed in jQuery 3.0 or newer as they handle it natively."));var c;window.requestAnimationFrame&&(a.fx.timer=function(d){d()&&a.timers.push(d)&&!c&&(c=!0,b())},a.fx.stop=function(){c=!1})}); -------------------------------------------------------------------------------- /docs/v1/_framework/scss/3rd/_animated.scss: -------------------------------------------------------------------------------- 1 | // From Font Awesome 2 | .#{$mdi-css-prefix}-spin:before { 3 | -webkit-animation: #{$mdi-css-prefix}-spin 2s infinite linear; 4 | animation: #{$mdi-css-prefix}-spin 2s infinite linear; 5 | } 6 | 7 | @-webkit-keyframes #{$mdi-css-prefix}-spin { 8 | 0% { 9 | -webkit-transform: rotate(0deg); 10 | transform: rotate(0deg); 11 | } 12 | 100% { 13 | -webkit-transform: rotate(359deg); 14 | transform: rotate(359deg); 15 | } 16 | } 17 | 18 | @keyframes #{$mdi-css-prefix}-spin { 19 | 0% { 20 | -webkit-transform: rotate(0deg); 21 | transform: rotate(0deg); 22 | } 23 | 100% { 24 | -webkit-transform: rotate(359deg); 25 | transform: rotate(359deg); 26 | } 27 | } -------------------------------------------------------------------------------- /docs/v1/_framework/scss/3rd/_core.scss: -------------------------------------------------------------------------------- 1 | .#{$mdi-css-prefix}:before, 2 | .#{$mdi-css-prefix}-set { 3 | display: inline-block; 4 | font: normal normal normal #{$mdi-font-size-base}/1 '#{$mdi-font-name}'; // shortening font declaration 5 | font-size: inherit; // can't have font-size inherit on line above, so need to override 6 | text-rendering: auto; // optimizelegibility throws things off #1094 7 | line-height: inherit; 8 | -webkit-font-smoothing: antialiased; 9 | -moz-osx-font-smoothing: grayscale; 10 | } -------------------------------------------------------------------------------- /docs/v1/_framework/scss/3rd/_functions.scss: -------------------------------------------------------------------------------- 1 | @function char($character-code) { 2 | @if function-exists("selector-append") { 3 | @return unquote("\"\\#{$character-code}\""); 4 | } 5 | 6 | @if "\\#{'x'}" == "\\x" { 7 | @return str-slice("\x", 1, 1) + $character-code; 8 | } 9 | @else { 10 | @return #{"\"\\"}#{$character-code + "\""}; 11 | } 12 | } 13 | 14 | @function mdi($name) { 15 | @if map-has-key($mdi-icons, $name) == false { 16 | @warn "Icon #{$name} not found."; 17 | @return ""; 18 | } 19 | @return char(map-get($mdi-icons, $name)); 20 | } -------------------------------------------------------------------------------- /docs/v1/_framework/scss/3rd/_icons.scss: -------------------------------------------------------------------------------- 1 | @each $key, $value in $mdi-icons { 2 | .#{$mdi-css-prefix}-#{$key}::before { 3 | content: char($value); 4 | } 5 | } 6 | 7 | .#{$mdi-css-prefix}-blank::before { 8 | content: "\F68C"; 9 | visibility: hidden; 10 | } -------------------------------------------------------------------------------- /docs/v1/_framework/scss/3rd/_path.scss: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: '#{$mdi-font-name}'; 3 | src: url('#{$mdi-font-path}/#{$mdi-filename}-webfont.eot?v=#{$mdi-version}'); 4 | src: url('#{$mdi-font-path}/#{$mdi-filename}-webfont.eot?#iefix&v=#{$mdi-version}') format('embedded-opentype'), 5 | url('#{$mdi-font-path}/#{$mdi-filename}-webfont.woff2?v=#{$mdi-version}') format('woff2'), 6 | url('#{$mdi-font-path}/#{$mdi-filename}-webfont.woff?v=#{$mdi-version}') format('woff'), 7 | url('#{$mdi-font-path}/#{$mdi-filename}-webfont.ttf?v=#{$mdi-version}') format('truetype'); 8 | font-weight: normal; 9 | font-style: normal; 10 | font-display: block; 11 | } 12 | -------------------------------------------------------------------------------- /docs/v1/_framework/scss/3rd/materialdesignicons.scss: -------------------------------------------------------------------------------- 1 | /* MaterialDesignIcons.com */ 2 | @import "variables"; 3 | @import "functions"; 4 | @import "path"; 5 | @import "core"; 6 | @import "icons"; 7 | @import "extras"; 8 | @import "animated"; -------------------------------------------------------------------------------- /docs/v1/design/_old/logo.ai: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KingSora/OverlayScrollbars/9cb3e2249f4be85e1e27753a85d20c00fc68cbda/docs/v1/design/_old/logo.ai -------------------------------------------------------------------------------- /docs/v1/design/_old/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KingSora/OverlayScrollbars/9cb3e2249f4be85e1e27753a85d20c00fc68cbda/docs/v1/design/_old/logo.png -------------------------------------------------------------------------------- /docs/v1/design/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KingSora/OverlayScrollbars/9cb3e2249f4be85e1e27753a85d20c00fc68cbda/docs/v1/design/favicon.png -------------------------------------------------------------------------------- /docs/v1/design/favicon.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KingSora/OverlayScrollbars/9cb3e2249f4be85e1e27753a85d20c00fc68cbda/docs/v1/design/favicon.psd -------------------------------------------------------------------------------- /docs/v1/design/logo.ai: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KingSora/OverlayScrollbars/9cb3e2249f4be85e1e27753a85d20c00fc68cbda/docs/v1/design/logo.ai -------------------------------------------------------------------------------- /docs/v1/design/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KingSora/OverlayScrollbars/9cb3e2249f4be85e1e27753a85d20c00fc68cbda/docs/v1/design/logo.png -------------------------------------------------------------------------------- /docs/v1/design/logo_backup.ai: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KingSora/OverlayScrollbars/9cb3e2249f4be85e1e27753a85d20c00fc68cbda/docs/v1/design/logo_backup.ai -------------------------------------------------------------------------------- /docs/v1/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KingSora/OverlayScrollbars/9cb3e2249f4be85e1e27753a85d20c00fc68cbda/docs/v1/favicon.ico -------------------------------------------------------------------------------- /docs/v1/frameworks/angular/angular.1effc66e349b0834b6d4.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 10 | 12 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /docs/v1/frameworks/angular/assets/angular.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 10 | 12 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /docs/v1/frameworks/angular/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KingSora/OverlayScrollbars/9cb3e2249f4be85e1e27753a85d20c00fc68cbda/docs/v1/frameworks/angular/favicon.ico -------------------------------------------------------------------------------- /docs/v1/frameworks/angular/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Example 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /docs/v1/frameworks/angular/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 10 | 12 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /docs/v1/frameworks/react/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KingSora/OverlayScrollbars/9cb3e2249f4be85e1e27753a85d20c00fc68cbda/docs/v1/frameworks/react/favicon.ico -------------------------------------------------------------------------------- /docs/v1/frameworks/react/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | } 10 | ], 11 | "start_url": ".", 12 | "display": "standalone", 13 | "theme_color": "#000000", 14 | "background_color": "#ffffff" 15 | } -------------------------------------------------------------------------------- /docs/v1/frameworks/react/precache-manifest.38429c8b057febf1cddfa242e6480d10.js: -------------------------------------------------------------------------------- 1 | self.__precacheManifest = (self.__precacheManifest || []).concat([ 2 | { 3 | "revision": "776484f4b1a15af2d2d27127124950e1", 4 | "url": "/OverlayScrollbars/frameworks/react/index.html" 5 | }, 6 | { 7 | "revision": "7229be741c2826c7fdac", 8 | "url": "/OverlayScrollbars/frameworks/react/static/css/2.cc8fcf68.chunk.css" 9 | }, 10 | { 11 | "revision": "9ddfd5e30809f01a7b07", 12 | "url": "/OverlayScrollbars/frameworks/react/static/css/main.957e9a21.chunk.css" 13 | }, 14 | { 15 | "revision": "7229be741c2826c7fdac", 16 | "url": "/OverlayScrollbars/frameworks/react/static/js/2.f58e91b4.chunk.js" 17 | }, 18 | { 19 | "revision": "9ddfd5e30809f01a7b07", 20 | "url": "/OverlayScrollbars/frameworks/react/static/js/main.1f7f80a4.chunk.js" 21 | }, 22 | { 23 | "revision": "d65fa28b079d6c287cca", 24 | "url": "/OverlayScrollbars/frameworks/react/static/js/runtime~main.6aaf21d4.js" 25 | }, 26 | { 27 | "revision": "bbebeed82d955073fab3b306cb78982d", 28 | "url": "/OverlayScrollbars/frameworks/react/static/media/overlayscrollbars.bbebeed8.svg" 29 | }, 30 | { 31 | "revision": "ba7f2cdb435590070d04b081fd4217df", 32 | "url": "/OverlayScrollbars/frameworks/react/static/media/react.ba7f2cdb.svg" 33 | } 34 | ]); -------------------------------------------------------------------------------- /docs/v1/frameworks/react/service-worker.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Welcome to your Workbox-powered service worker! 3 | * 4 | * You'll need to register this file in your web app and you should 5 | * disable HTTP caching for this file too. 6 | * See https://goo.gl/nhQhGp 7 | * 8 | * The rest of the code is auto-generated. Please don't update this file 9 | * directly; instead, make changes to your Workbox build configuration 10 | * and re-run your build process. 11 | * See https://goo.gl/2aRDsh 12 | */ 13 | 14 | importScripts("https://storage.googleapis.com/workbox-cdn/releases/4.3.1/workbox-sw.js"); 15 | 16 | importScripts( 17 | "/OverlayScrollbars/frameworks/react/precache-manifest.38429c8b057febf1cddfa242e6480d10.js" 18 | ); 19 | 20 | self.addEventListener('message', (event) => { 21 | if (event.data && event.data.type === 'SKIP_WAITING') { 22 | self.skipWaiting(); 23 | } 24 | }); 25 | 26 | workbox.core.clientsClaim(); 27 | 28 | /** 29 | * The workboxSW.precacheAndRoute() method efficiently caches and responds to 30 | * requests for URLs in the manifest. 31 | * See https://goo.gl/S9QRab 32 | */ 33 | self.__precacheManifest = [].concat(self.__precacheManifest || []); 34 | workbox.precaching.precacheAndRoute(self.__precacheManifest, {}); 35 | 36 | workbox.routing.registerNavigationRoute(workbox.precaching.getCacheKeyForURL("/OverlayScrollbars/frameworks/react/index.html"), { 37 | 38 | blacklist: [/^\/_/,/\/[^/]+\.[^/]+$/], 39 | }); 40 | -------------------------------------------------------------------------------- /docs/v1/frameworks/vue/assets/vue.82507c49.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /docs/v1/frameworks/vue/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KingSora/OverlayScrollbars/9cb3e2249f4be85e1e27753a85d20c00fc68cbda/docs/v1/frameworks/vue/favicon.ico -------------------------------------------------------------------------------- /docs/v1/frameworks/vue/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | OverlayScrollvars Vue App 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /docs/v1/frameworks/vue/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /docs/v1/google3e52b79b0ab45056.html: -------------------------------------------------------------------------------- 1 | google-site-verification: google3e52b79b0ab45056.html -------------------------------------------------------------------------------- /docs/v1/html/extensions.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |

Extensions

5 |
6 | This is the official extensions page for OverlayScrollbars.
7 | Here you can find Extensions written by myself or by the community.

8 | 9 | If you wanna know how to write your own Extension, please read the documentation and check the examples.
10 | In case you've written your own Extension and you to want make it available for everyone, please open a issue on github. 11 | After I've reviewed your extension it will be listed on this page. 12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 | Searching Extensions... 24 |
25 | 26 | 27 |
28 | 29 |
30 |
31 |
32 |
33 |
-------------------------------------------------------------------------------- /docs/v1/img/browserstack.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KingSora/OverlayScrollbars/9cb3e2249f4be85e1e27753a85d20c00fc68cbda/docs/v1/img/browserstack.png -------------------------------------------------------------------------------- /docs/v1/img/demo_content_annie.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KingSora/OverlayScrollbars/9cb3e2249f4be85e1e27753a85d20c00fc68cbda/docs/v1/img/demo_content_annie.png -------------------------------------------------------------------------------- /docs/v1/img/demo_content_connie.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KingSora/OverlayScrollbars/9cb3e2249f4be85e1e27753a85d20c00fc68cbda/docs/v1/img/demo_content_connie.png -------------------------------------------------------------------------------- /docs/v1/img/demo_content_eren.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KingSora/OverlayScrollbars/9cb3e2249f4be85e1e27753a85d20c00fc68cbda/docs/v1/img/demo_content_eren.png -------------------------------------------------------------------------------- /docs/v1/img/demo_content_erwin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KingSora/OverlayScrollbars/9cb3e2249f4be85e1e27753a85d20c00fc68cbda/docs/v1/img/demo_content_erwin.png -------------------------------------------------------------------------------- /docs/v1/img/demo_content_levi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KingSora/OverlayScrollbars/9cb3e2249f4be85e1e27753a85d20c00fc68cbda/docs/v1/img/demo_content_levi.png -------------------------------------------------------------------------------- /docs/v1/img/demo_content_mikasa.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KingSora/OverlayScrollbars/9cb3e2249f4be85e1e27753a85d20c00fc68cbda/docs/v1/img/demo_content_mikasa.png -------------------------------------------------------------------------------- /docs/v1/img/demo_content_reiner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KingSora/OverlayScrollbars/9cb3e2249f4be85e1e27753a85d20c00fc68cbda/docs/v1/img/demo_content_reiner.png -------------------------------------------------------------------------------- /docs/v1/img/demo_content_sasha.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KingSora/OverlayScrollbars/9cb3e2249f4be85e1e27753a85d20c00fc68cbda/docs/v1/img/demo_content_sasha.png -------------------------------------------------------------------------------- /docs/v1/index.dev.js: -------------------------------------------------------------------------------- 1 | $(function(){ 2 | window._framework.buildPage({ 3 | defaultHash : 'overview' 4 | }); 5 | /* 6 | OverlayScrollbars($('#div')[0], { 7 | nativeScrollbarsOverlaid : { 8 | initialize: false 9 | } 10 | }).destroy(); 11 | 12 | OverlayScrollbars($('#text')[0], { 13 | nativeScrollbarsOverlaid : { 14 | initialize: false 15 | } 16 | }).destroy(); 17 | */ 18 | }); 19 | 20 | -------------------------------------------------------------------------------- /docs/v1/index.js: -------------------------------------------------------------------------------- 1 | /* 3rd party */ 2 | import "./_framework/plugins/js/jquery.min.js"; 3 | import "./_framework/plugins/js/jquery.raf.min.js"; 4 | import "./_framework/plugins/js/jquery.easing.js"; 5 | import "./_framework/plugins/js/day.min.js"; 6 | import "./_framework/plugins/js/tippy.min.js"; 7 | import "./_framework/plugins/js/highlight.min.js"; 8 | import "./_framework/plugins/js/signals.min.js"; 9 | import "./_framework/plugins/js/hasher.min.js"; 10 | import "./_framework/plugins/js/codemirror/codemirror.min.js"; 11 | import "./_framework/plugins/js/codemirror/mode/javascript.min.js"; 12 | import "./_framework/plugins/js/viewport-units-buggyfill.min.js"; 13 | 14 | import "./_framework/js/framework.js"; 15 | import "./_framework/js/jquery.overlayScrollbars.js"; 16 | 17 | $(function () { 18 | window._framework.buildPage({ 19 | defaultHash: "overview", 20 | }); 21 | }); 22 | -------------------------------------------------------------------------------- /docs/v1/js/overview.js: -------------------------------------------------------------------------------- 1 | undefined -------------------------------------------------------------------------------- /docs/v1/pleeease--watch.bat: -------------------------------------------------------------------------------- 1 | pleeease watch 2 | pause -------------------------------------------------------------------------------- /docs/v1/rollup-c.bat: -------------------------------------------------------------------------------- 1 | call rollup -c 2 | call uglifyjs ./index.bundle.js -o ./index.min.js -c -m --ie8 3 | del "./index.bundle.js" 4 | del "./index.bundle.js.map" 5 | pause -------------------------------------------------------------------------------- /docs/v1/rollup.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | context: 'this', 3 | input: 'index.js', 4 | output: { 5 | file: 'index.bundle.js', 6 | format: 'cjs', 7 | exports: 'named', 8 | sourcemap: true, 9 | strict : false 10 | } 11 | }; -------------------------------------------------------------------------------- /docs/v1/sass--watch.bat: -------------------------------------------------------------------------------- 1 | sass --watch styles.scss:styles.min.css 2 | pause -------------------------------------------------------------------------------- /examples/angular/.gitignore: -------------------------------------------------------------------------------- 1 | # See http://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # Compiled output 4 | /build 5 | /dist 6 | /tmp 7 | /out-tsc 8 | /bazel-out 9 | 10 | # Node 11 | /node_modules 12 | npm-debug.log 13 | yarn-error.log 14 | 15 | # IDEs and editors 16 | .idea/ 17 | .project 18 | .classpath 19 | .c9/ 20 | *.launch 21 | .settings/ 22 | *.sublime-workspace 23 | 24 | # Visual Studio Code 25 | .vscode/* 26 | !.vscode/settings.json 27 | !.vscode/tasks.json 28 | !.vscode/launch.json 29 | !.vscode/extensions.json 30 | .history/* 31 | 32 | # Miscellaneous 33 | /.angular 34 | /.angular/cache 35 | .sass-cache/ 36 | /connect.lock 37 | /coverage 38 | /libpeerconnection.log 39 | testem.log 40 | /typings 41 | 42 | # System files 43 | .DS_Store 44 | Thumbs.db 45 | -------------------------------------------------------------------------------- /examples/angular/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "type": "module", 4 | "dependencies": { 5 | "@angular/animations": "^17.0.7", 6 | "@angular/common": "^17.0.7", 7 | "@angular/compiler": "^17.0.7", 8 | "@angular/core": "^17.0.7", 9 | "@angular/forms": "^17.0.7", 10 | "@angular/platform-browser": "^17.0.7", 11 | "@angular/platform-browser-dynamic": "^17.0.7", 12 | "@angular/router": "^17.0.7", 13 | "overlayscrollbars": "file:../../packages/overlayscrollbars/dist", 14 | "overlayscrollbars-ngx": "file:../../packages/overlayscrollbars-ngx/dist", 15 | "rxjs": "^7.8.1", 16 | "tslib": "^2.6.2", 17 | "zone.js": "^0.14.0" 18 | }, 19 | "devDependencies": { 20 | "@angular-devkit/build-angular": "^17.0.7", 21 | "@angular/cli": "^17.0.7", 22 | "@angular/compiler-cli": "^17.0.7", 23 | "typescript": "~5.2.0" 24 | }, 25 | "scripts": { 26 | "ng": "ng", 27 | "dev": "ng serve", 28 | "build": "ng build --base-href /OverlayScrollbars/example/angular/", 29 | "watch": "ng build --watch --configuration development" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /examples/angular/src/app/app.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { BrowserModule } from '@angular/platform-browser'; 3 | import { OverlayscrollbarsModule } from 'overlayscrollbars-ngx'; 4 | 5 | import { AppComponent } from './app.component'; 6 | 7 | @NgModule({ 8 | declarations: [AppComponent], 9 | imports: [BrowserModule, OverlayscrollbarsModule], 10 | providers: [], 11 | bootstrap: [AppComponent], 12 | }) 13 | export class AppModule {} 14 | -------------------------------------------------------------------------------- /examples/angular/src/assets/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /examples/angular/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 14 | OverlayScrollbars & Angular 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /examples/angular/src/main.ts: -------------------------------------------------------------------------------- 1 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 2 | import { OverlayScrollbars, ClickScrollPlugin } from 'overlayscrollbars'; 3 | import { AppModule } from './app/app.module'; 4 | 5 | OverlayScrollbars.plugin(ClickScrollPlugin); 6 | 7 | platformBrowserDynamic() 8 | .bootstrapModule(AppModule) 9 | .catch((err) => console.error(err)); 10 | -------------------------------------------------------------------------------- /examples/angular/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "extends": "./tsconfig.json", 4 | "compilerOptions": { 5 | "outDir": "./out-tsc/app", 6 | "types": [] 7 | }, 8 | "files": [ 9 | "src/main.ts", 10 | "src/polyfills.ts" 11 | ], 12 | "include": [ 13 | "src/**/*.d.ts" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /examples/angular/tsconfig.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "compileOnSave": false, 4 | "compilerOptions": { 5 | "baseUrl": "./", 6 | "outDir": "./dist/out-tsc", 7 | "forceConsistentCasingInFileNames": true, 8 | "strict": true, 9 | "noImplicitOverride": true, 10 | "noPropertyAccessFromIndexSignature": true, 11 | "noImplicitReturns": true, 12 | "noFallthroughCasesInSwitch": true, 13 | "sourceMap": true, 14 | "declaration": false, 15 | "downlevelIteration": true, 16 | "experimentalDecorators": true, 17 | "moduleResolution": "node", 18 | "importHelpers": true, 19 | "target": "ES2022", 20 | "module": "es2020", 21 | "lib": [ 22 | "es2020", 23 | "dom" 24 | ] 25 | }, 26 | "angularCompilerOptions": { 27 | "enableI18nLegacyMessageIdFormat": false, 28 | "strictInjectionParameters": true, 29 | "strictInputAccessModifiers": true, 30 | "strictTemplates": true 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /examples/browser/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | build 12 | build-ssr 13 | dist 14 | dist-ssr 15 | *.local 16 | 17 | # Editor directories and files 18 | .vscode/* 19 | !.vscode/extensions.json 20 | .idea 21 | .DS_Store 22 | *.suo 23 | *.ntvs* 24 | *.njsproj 25 | *.sln 26 | *.sw? 27 | -------------------------------------------------------------------------------- /examples/browser/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "type": "module", 4 | "devDependencies": { 5 | "vite": "^5.2.11" 6 | }, 7 | "scripts": { 8 | "dev": "vite", 9 | "build": "vite build --base /OverlayScrollbars/example/cdn", 10 | "preview": "vite preview" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /examples/browser/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KingSora/OverlayScrollbars/9cb3e2249f4be85e1e27753a85d20c00fc68cbda/examples/browser/public/favicon.ico -------------------------------------------------------------------------------- /examples/browser/public/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KingSora/OverlayScrollbars/9cb3e2249f4be85e1e27753a85d20c00fc68cbda/examples/browser/public/logo.png -------------------------------------------------------------------------------- /examples/browser/script.js: -------------------------------------------------------------------------------- 1 | const { OverlayScrollbars, ClickScrollPlugin } = OverlayScrollbarsGlobal; 2 | 3 | // optional: use the ClickScrollPlugin to make the option "scrollbars.clickScroll: true" available 4 | OverlayScrollbars.plugin(ClickScrollPlugin); 5 | 6 | OverlayScrollbars(document.body, { 7 | scrollbars: { 8 | clickScroll: true, 9 | }, 10 | }); 11 | OverlayScrollbars(document.getElementById('target'), {}); 12 | -------------------------------------------------------------------------------- /examples/browser/vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite'; 2 | 3 | export default defineConfig({ 4 | build: { 5 | outDir: 'dist', 6 | }, 7 | resolve: { 8 | preserveSymlinks: true, 9 | }, 10 | optimizeDeps: { 11 | exclude: ['overlayscrollbars'], 12 | }, 13 | }); 14 | -------------------------------------------------------------------------------- /examples/node/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | build 12 | build-ssr 13 | dist 14 | dist-ssr 15 | *.local 16 | 17 | # Editor directories and files 18 | .vscode/* 19 | !.vscode/extensions.json 20 | .idea 21 | .DS_Store 22 | *.suo 23 | *.ntvs* 24 | *.njsproj 25 | *.sln 26 | *.sw? 27 | -------------------------------------------------------------------------------- /examples/node/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "type": "module", 4 | "dependencies": { 5 | "overlayscrollbars": "file:../../packages/overlayscrollbars/dist" 6 | }, 7 | "devDependencies": { 8 | "vite": "^5.2.11" 9 | }, 10 | "scripts": { 11 | "dev": "vite", 12 | "build": "vite build --base /OverlayScrollbars/example/cdn", 13 | "preview": "vite preview" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /examples/node/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KingSora/OverlayScrollbars/9cb3e2249f4be85e1e27753a85d20c00fc68cbda/examples/node/public/favicon.ico -------------------------------------------------------------------------------- /examples/node/public/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KingSora/OverlayScrollbars/9cb3e2249f4be85e1e27753a85d20c00fc68cbda/examples/node/public/logo.png -------------------------------------------------------------------------------- /examples/node/src/script.js: -------------------------------------------------------------------------------- 1 | import 'overlayscrollbars/overlayscrollbars.css'; 2 | import { OverlayScrollbars, ClickScrollPlugin } from 'OverlayScrollbars'; 3 | 4 | // optional: use the ClickScrollPlugin to make the option "scrollbars.clickScroll: true" available 5 | OverlayScrollbars.plugin(ClickScrollPlugin); 6 | 7 | OverlayScrollbars(document.body, { 8 | scrollbars: { 9 | clickScroll: true, 10 | }, 11 | }); 12 | OverlayScrollbars(document.getElementById('target'), {}); 13 | -------------------------------------------------------------------------------- /examples/node/vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite'; 2 | 3 | export default defineConfig({ 4 | build: { 5 | outDir: 'dist', 6 | }, 7 | resolve: { 8 | preserveSymlinks: true, 9 | }, 10 | optimizeDeps: { 11 | exclude: ['overlayscrollbars'], 12 | }, 13 | }); 14 | -------------------------------------------------------------------------------- /examples/overlayscrollbars/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | build 12 | build-ssr 13 | dist 14 | dist-ssr 15 | *.local 16 | 17 | # Editor directories and files 18 | .vscode/* 19 | !.vscode/extensions.json 20 | .idea 21 | .DS_Store 22 | *.suo 23 | *.ntvs* 24 | *.njsproj 25 | *.sln 26 | *.sw? 27 | -------------------------------------------------------------------------------- /examples/overlayscrollbars/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "type": "module", 4 | "dependencies": { 5 | "overlayscrollbars": "file:../../packages/overlayscrollbars/dist" 6 | }, 7 | "devDependencies": { 8 | "typescript": "^5.0.2", 9 | "vite": "^5.2.11" 10 | }, 11 | "scripts": { 12 | "dev": "vite", 13 | "build": "tsc && vite build --base /OverlayScrollbars/example/overlayscrollbars", 14 | "preview": "vite preview" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /examples/overlayscrollbars/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KingSora/OverlayScrollbars/9cb3e2249f4be85e1e27753a85d20c00fc68cbda/examples/overlayscrollbars/public/favicon.ico -------------------------------------------------------------------------------- /examples/overlayscrollbars/public/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KingSora/OverlayScrollbars/9cb3e2249f4be85e1e27753a85d20c00fc68cbda/examples/overlayscrollbars/public/logo.png -------------------------------------------------------------------------------- /examples/overlayscrollbars/src/index.ts: -------------------------------------------------------------------------------- 1 | import 'overlayscrollbars/overlayscrollbars.css'; 2 | import { OverlayScrollbars, ClickScrollPlugin } from 'overlayscrollbars'; 3 | import './actions.ts'; 4 | import './bodyOverlayScrollbars.ts'; 5 | 6 | OverlayScrollbars.plugin(ClickScrollPlugin); 7 | -------------------------------------------------------------------------------- /examples/overlayscrollbars/src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /examples/overlayscrollbars/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "useDefineForClassFields": true, 5 | "module": "NodeNext", 6 | "lib": ["ES2020", "DOM", "DOM.Iterable"], 7 | "skipLibCheck": true, 8 | 9 | /* Bundler mode */ 10 | "moduleResolution": "NodeNext", 11 | "allowImportingTsExtensions": true, 12 | "resolveJsonModule": true, 13 | "isolatedModules": true, 14 | "noEmit": true, 15 | 16 | /* Linting */ 17 | "strict": true, 18 | "noUnusedLocals": true, 19 | "noUnusedParameters": true, 20 | "noFallthroughCasesInSwitch": true 21 | }, 22 | "include": ["src"] 23 | } 24 | -------------------------------------------------------------------------------- /examples/overlayscrollbars/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite'; 2 | 3 | export default defineConfig({ 4 | build: { 5 | outDir: 'dist', 6 | }, 7 | resolve: { 8 | preserveSymlinks: true, 9 | }, 10 | optimizeDeps: { 11 | exclude: ['overlayscrollbars'], 12 | }, 13 | }); 14 | -------------------------------------------------------------------------------- /examples/react/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | build 12 | build-ssr 13 | dist 14 | dist-ssr 15 | *.local 16 | 17 | # Editor directories and files 18 | .vscode/* 19 | !.vscode/extensions.json 20 | .idea 21 | .DS_Store 22 | *.suo 23 | *.ntvs* 24 | *.njsproj 25 | *.sln 26 | *.sw? 27 | -------------------------------------------------------------------------------- /examples/react/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 13 | OverlayScrollbars & React 14 | 15 | 16 |
17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /examples/react/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "type": "module", 4 | "dependencies": { 5 | "overlayscrollbars": "file:../../packages/overlayscrollbars/dist", 6 | "overlayscrollbars-react": "file:../../packages/overlayscrollbars-react/dist", 7 | "react": "^18.2.0", 8 | "react-dom": "^18.2.0" 9 | }, 10 | "devDependencies": { 11 | "@types/react": "^18.2.45", 12 | "@types/react-dom": "^18.2.17", 13 | "@vitejs/plugin-react": "^4.2.1", 14 | "typescript": "^5.0.2", 15 | "vite": "^5.2.11" 16 | }, 17 | "scripts": { 18 | "dev": "vite", 19 | "build": "tsc && vite build --base /OverlayScrollbars/example/react", 20 | "preview": "vite preview" 21 | } 22 | } -------------------------------------------------------------------------------- /examples/react/src/main.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom/client'; 3 | import { OverlayScrollbars, ClickScrollPlugin } from 'overlayscrollbars'; 4 | import 'overlayscrollbars/overlayscrollbars.css'; 5 | import './index.css'; 6 | import App from './App'; 7 | 8 | OverlayScrollbars.plugin(ClickScrollPlugin); 9 | 10 | const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement); 11 | root.render( 12 | 13 | 14 | 15 | ); 16 | -------------------------------------------------------------------------------- /examples/react/src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /examples/react/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ESNext", 4 | "useDefineForClassFields": true, 5 | "lib": ["DOM", "DOM.Iterable", "ESNext"], 6 | "allowJs": false, 7 | "skipLibCheck": true, 8 | "esModuleInterop": false, 9 | "allowSyntheticDefaultImports": true, 10 | "strict": true, 11 | "forceConsistentCasingInFileNames": true, 12 | "module": "ESNext", 13 | "moduleResolution": "Node", 14 | "resolveJsonModule": true, 15 | "isolatedModules": true, 16 | "noEmit": true, 17 | "jsx": "react-jsx" 18 | }, 19 | "include": ["src"], 20 | "references": [{ "path": "./tsconfig.node.json" }] 21 | } 22 | -------------------------------------------------------------------------------- /examples/react/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "composite": true, 4 | "module": "ESNext", 5 | "moduleResolution": "Node", 6 | "allowSyntheticDefaultImports": true 7 | }, 8 | "include": ["vite.config.ts"] 9 | } 10 | -------------------------------------------------------------------------------- /examples/react/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite'; 2 | import react from '@vitejs/plugin-react'; 3 | 4 | // https://vitejs.dev/config/ 5 | export default defineConfig({ 6 | build: { 7 | outDir: 'dist', 8 | }, 9 | resolve: { 10 | preserveSymlinks: true, 11 | }, 12 | optimizeDeps: { 13 | exclude: ['overlayscrollbars', 'overlayscrollbars-react'], 14 | }, 15 | plugins: [react()], 16 | }); 17 | -------------------------------------------------------------------------------- /examples/solid/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | build 3 | build-ssr 4 | dist -------------------------------------------------------------------------------- /examples/solid/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 13 | OverlayScrollbars & Solid 14 | 15 | 16 |
17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /examples/solid/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "type": "module", 4 | "dependencies": { 5 | "overlayscrollbars": "file:../../packages/overlayscrollbars/dist", 6 | "overlayscrollbars-solid": "file:../../packages/overlayscrollbars-solid/dist", 7 | "solid-js": "^1.9.3" 8 | }, 9 | "devDependencies": { 10 | "typescript": "^5.0.2", 11 | "vite": "^5.2.11", 12 | "vite-plugin-solid": "^2.10.1" 13 | }, 14 | "scripts": { 15 | "start": "vite", 16 | "dev": "vite", 17 | "build": "vite build --base /OverlayScrollbars/example/solid", 18 | "serve": "vite preview" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /examples/solid/src/index.tsx: -------------------------------------------------------------------------------- 1 | /* @refresh reload */ 2 | import 'overlayscrollbars/overlayscrollbars.css'; 3 | import { OverlayScrollbars, ClickScrollPlugin } from 'overlayscrollbars'; 4 | import { render } from 'solid-js/web'; 5 | 6 | import './index.css'; 7 | import App from './App'; 8 | 9 | OverlayScrollbars.plugin(ClickScrollPlugin); 10 | 11 | render(() => , document.getElementById('root') as HTMLElement); 12 | -------------------------------------------------------------------------------- /examples/solid/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "strict": true, 4 | "target": "ESNext", 5 | "module": "ESNext", 6 | "moduleResolution": "node", 7 | "allowSyntheticDefaultImports": true, 8 | "esModuleInterop": true, 9 | "jsx": "preserve", 10 | "jsxImportSource": "solid-js", 11 | "types": ["vite/client"], 12 | "noEmit": true, 13 | "isolatedModules": true 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /examples/solid/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite'; 2 | import solidPlugin from 'vite-plugin-solid'; 3 | 4 | export default defineConfig({ 5 | build: { 6 | outDir: 'dist', 7 | }, 8 | resolve: { 9 | preserveSymlinks: true, 10 | }, 11 | optimizeDeps: { 12 | exclude: ['overlayscrollbars', 'overlayscrollbars-solid'], 13 | }, 14 | plugins: [solidPlugin()], 15 | }); 16 | -------------------------------------------------------------------------------- /examples/svelte/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | build 14 | build-ssr 15 | *.local 16 | 17 | # Editor directories and files 18 | .vscode/* 19 | !.vscode/extensions.json 20 | .idea 21 | .DS_Store 22 | *.suo 23 | *.ntvs* 24 | *.njsproj 25 | *.sln 26 | *.sw? 27 | -------------------------------------------------------------------------------- /examples/svelte/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 14 | OverlayScrollbars & Svelte 15 | 16 | 17 |
18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /examples/svelte/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "type": "module", 4 | "dependencies": { 5 | "overlayscrollbars": "file:../../packages/overlayscrollbars/dist", 6 | "overlayscrollbars-svelte": "file:../../packages/overlayscrollbars-svelte/dist" 7 | }, 8 | "devDependencies": { 9 | "@sveltejs/vite-plugin-svelte": "^5.0.3", 10 | "@tsconfig/svelte": "^5.0.4", 11 | "svelte": "^5.0.0", 12 | "svelte-check": "^4.1.4", 13 | "tslib": "^2.6.0", 14 | "typescript": "^5.0.2", 15 | "vite": "^6.0.0" 16 | }, 17 | "scripts": { 18 | "dev": "vite", 19 | "build": "vite build --base /OverlayScrollbars/example/svelte", 20 | "preview": "vite preview", 21 | "check": "svelte-check --tsconfig ./tsconfig.json" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /examples/svelte/src/main.ts: -------------------------------------------------------------------------------- 1 | import 'overlayscrollbars/overlayscrollbars.css'; 2 | import { OverlayScrollbars, ClickScrollPlugin } from 'overlayscrollbars'; 3 | import './app.css'; 4 | import { mount } from 'svelte'; 5 | import App from './App.svelte'; 6 | 7 | OverlayScrollbars.plugin(ClickScrollPlugin); 8 | 9 | const app = mount(App, { target: document.getElementById('app') as HTMLElement }); 10 | 11 | export default app; 12 | -------------------------------------------------------------------------------- /examples/svelte/src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | -------------------------------------------------------------------------------- /examples/svelte/svelte.config.js: -------------------------------------------------------------------------------- 1 | import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'; 2 | 3 | export default { 4 | // Consult https://svelte.dev/docs#compile-time-svelte-preprocess 5 | // for more information about preprocessors 6 | preprocess: vitePreprocess(), 7 | }; 8 | -------------------------------------------------------------------------------- /examples/svelte/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@tsconfig/svelte/tsconfig.json", 3 | "compilerOptions": { 4 | "target": "ESNext", 5 | "useDefineForClassFields": true, 6 | "module": "ESNext", 7 | "resolveJsonModule": true, 8 | /** 9 | * Typecheck JS in `.svelte` and `.js` files by default. 10 | * Disable checkJs if you'd like to use dynamic types in JS. 11 | * Note that setting allowJs false does not prevent the use 12 | * of JS in `.svelte` files. 13 | */ 14 | "allowJs": true, 15 | "checkJs": true, 16 | "isolatedModules": true 17 | }, 18 | "include": ["src/**/*.d.ts", "src/**/*.ts", "src/**/*.js", "src/**/*.svelte"], 19 | "references": [{ "path": "./tsconfig.node.json" }] 20 | } 21 | -------------------------------------------------------------------------------- /examples/svelte/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "composite": true, 4 | "skipLibCheck": true, 5 | "module": "ESNext", 6 | "moduleResolution": "bundler" 7 | }, 8 | "include": ["vite.config.ts"] 9 | } 10 | -------------------------------------------------------------------------------- /examples/svelte/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite'; 2 | import { svelte } from '@sveltejs/vite-plugin-svelte'; 3 | 4 | // https://vitejs.dev/config/ 5 | export default defineConfig({ 6 | build: { 7 | outDir: 'dist', 8 | }, 9 | resolve: { 10 | preserveSymlinks: true, 11 | }, 12 | optimizeDeps: { 13 | exclude: ['overlayscrollbars', 'overlayscrollbars-svelte'], 14 | }, 15 | plugins: [svelte()], 16 | }); 17 | -------------------------------------------------------------------------------- /examples/vue/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | .DS_Store 12 | build 13 | build-ssr 14 | dist 15 | dist-ssr 16 | coverage 17 | *.local 18 | 19 | /cypress/videos/ 20 | /cypress/screenshots/ 21 | 22 | # Editor directories and files 23 | .vscode/* 24 | !.vscode/extensions.json 25 | .idea 26 | *.suo 27 | *.ntvs* 28 | *.njsproj 29 | *.sln 30 | *.sw? 31 | -------------------------------------------------------------------------------- /examples/vue/env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | declare module '*.vue' { 4 | const vue: any; 5 | export default vue; 6 | } 7 | -------------------------------------------------------------------------------- /examples/vue/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 13 | OverlayScrollbars & Vue 14 | 15 | 16 |
17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /examples/vue/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "type": "module", 4 | "dependencies": { 5 | "overlayscrollbars": "file:../../packages/overlayscrollbars/dist", 6 | "overlayscrollbars-vue": "file:../../packages/overlayscrollbars-vue/dist", 7 | "vue": "^3.4.21" 8 | }, 9 | "devDependencies": { 10 | "@types/node": "^20.10.5", 11 | "@vitejs/plugin-vue": "^5.2.1", 12 | "@vitejs/plugin-vue-jsx": "^4.1.1", 13 | "@vue/tsconfig": "^0.5.1", 14 | "typescript": "^5.0.2", 15 | "vite": "^5.2.11", 16 | "vue-tsc": "^1.8.25" 17 | }, 18 | "scripts": { 19 | "dev": "vite", 20 | "build": "run-p type-check build-only", 21 | "preview": "vite preview --port 4173", 22 | "build-only": "vite build --base /OverlayScrollbars/example/vue", 23 | "type-check": "vue-tsc --noEmit" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /examples/vue/public/logo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/vue/src/main.ts: -------------------------------------------------------------------------------- 1 | import 'overlayscrollbars/overlayscrollbars.css'; 2 | import { createApp } from 'vue'; 3 | import { OverlayScrollbars, ClickScrollPlugin } from 'overlayscrollbars'; 4 | import App from './App.vue'; 5 | 6 | import './main.css'; 7 | 8 | OverlayScrollbars.plugin(ClickScrollPlugin); 9 | 10 | const app = createApp(App); 11 | app.mount('#app'); 12 | -------------------------------------------------------------------------------- /examples/vue/tsconfig.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@vue/tsconfig/tsconfig.json", 3 | "include": ["vite.config.*", "vitest.config.*", "cypress.config.*"], 4 | "compilerOptions": { 5 | "ignoreDeprecations": "5.0", 6 | "composite": true, 7 | "noEmit": false, 8 | "types": ["node"] 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /examples/vue/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@vue/tsconfig/tsconfig.dom.json", 3 | "include": ["env.d.ts", "src/**/*", "src/**/*.vue"], 4 | "compilerOptions": { 5 | "ignoreDeprecations": "5.0", 6 | "baseUrl": ".", 7 | "lib": [ 8 | "ES2017", 9 | "DOM", 10 | "DOM.Iterable" 11 | ], 12 | "paths": { 13 | "@/*": ["./src/*"] 14 | } 15 | }, 16 | "references": [ 17 | { 18 | "path": "./tsconfig.config.json" 19 | } 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /examples/vue/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { fileURLToPath, URL } from 'node:url'; 2 | 3 | import { defineConfig } from 'vite'; 4 | import vue from '@vitejs/plugin-vue'; 5 | import vueJsx from '@vitejs/plugin-vue-jsx'; 6 | 7 | // https://vitejs.dev/config/ 8 | export default defineConfig({ 9 | build: { 10 | outDir: 'dist', 11 | }, 12 | plugins: [ 13 | vue({ 14 | template: { 15 | transformAssetUrls: { 16 | includeAbsolute: false, 17 | }, 18 | }, 19 | }), 20 | vueJsx(), 21 | ], 22 | resolve: { 23 | preserveSymlinks: true, 24 | alias: { 25 | '@': fileURLToPath(new URL('./src', import.meta.url)), 26 | }, 27 | }, 28 | optimizeDeps: { 29 | exclude: ['overlayscrollbars', 'overlayscrollbars-vue'], 30 | }, 31 | }); 32 | -------------------------------------------------------------------------------- /local/browser-testing/.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled output 2 | /dist 3 | -------------------------------------------------------------------------------- /local/browser-testing/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@~local/browser-testing", 3 | "private": true, 4 | "type": "module", 5 | "version": "0.0.0", 6 | "main": "./dist/index.js", 7 | "types": "./dist/index.d.ts", 8 | "scripts": { 9 | "postinstall": "tsc --project ./tsconfig.json" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /local/browser-testing/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './select'; 2 | export * from './testResult'; 3 | export * from './timeout'; 4 | export * from './resize'; 5 | -------------------------------------------------------------------------------- /local/browser-testing/src/testResult.ts: -------------------------------------------------------------------------------- 1 | import { waitFor, waitForOptions } from '@testing-library/dom'; 2 | 3 | const getTestResultElm = () => document.getElementById('testResult'); 4 | 5 | export const setTestResult = (result: boolean | null) => { 6 | const elm = getTestResultElm(); 7 | if (elm) { 8 | if (typeof result === 'boolean') { 9 | if (result) { 10 | if (elm.getAttribute('class') === 'failed') { 11 | return; 12 | } 13 | } 14 | elm.setAttribute('class', result ? 'passed' : 'failed'); 15 | } else { 16 | elm.removeAttribute('class'); 17 | } 18 | } 19 | }; 20 | 21 | export const testPassed = (): boolean => { 22 | const elm = getTestResultElm(); 23 | return elm ? elm.getAttribute('class') === 'passed' : false; 24 | }; 25 | 26 | export const waitForOrFailTest = (callback: () => T | Promise, options?: waitForOptions) => 27 | waitFor(callback, { 28 | ...options, 29 | onTimeout(error: Error): Error { 30 | setTestResult(false); 31 | return error; 32 | }, 33 | }); 34 | -------------------------------------------------------------------------------- /local/browser-testing/src/timeout.ts: -------------------------------------------------------------------------------- 1 | export const timeout = (ms: number) => 2 | new Promise((resolve) => { 3 | setTimeout(resolve, ms); 4 | }); 5 | -------------------------------------------------------------------------------- /local/browser-testing/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@~local/tsconfig", 3 | "compilerOptions": { 4 | "outDir": "./dist/", 5 | "baseUrl": "./src/", 6 | "module": "ESNext", 7 | "typeRoots": [] 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /local/config/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@~local/config", 3 | "type": "module", 4 | "private": true, 5 | "exports": { 6 | "./resolve": "./src/resolve.json", 7 | "./playwright": "./src/playwright.js", 8 | "./playwright-coverage": "./src/playwright-coverage.js", 9 | "./full-coverage": "./src/full-coverage.js", 10 | "./vitest": "./src/vitest.js", 11 | "./vitest-coverage": "./src/vitest-coverage.js" 12 | }, 13 | "version": "0.0.0" 14 | } 15 | -------------------------------------------------------------------------------- /local/config/src/full-coverage.js: -------------------------------------------------------------------------------- 1 | export const fullCoverage = { 2 | tmpCoverageDirectory: './.coverage/.nycFull', 3 | coverageDirectory: './.coverage/full', 4 | }; 5 | -------------------------------------------------------------------------------- /local/config/src/playwright-coverage.js: -------------------------------------------------------------------------------- 1 | export const playwrightCoverage = { 2 | tmpCoverageDirectory: './.coverage/.nycPlaywright', 3 | coverageDirectory: './.coverage/e2e', 4 | }; 5 | -------------------------------------------------------------------------------- /local/config/src/playwright.js: -------------------------------------------------------------------------------- 1 | import { devices } from '@playwright/test'; 2 | 3 | export default { 4 | testMatch: /.*\/test\/playwright\/.*\.test\.[jt]sx?/, 5 | timeout: 10 * 60 * 1500, 6 | navigationTimeout: 1000, 7 | retries: 1, 8 | maxFailures: 0, 9 | workers: 4, 10 | fullyParallel: true, 11 | reporter: 'list', 12 | outputDir: '.playwright', 13 | projects: [ 14 | { 15 | name: 'Chromium', 16 | use: { 17 | ...devices['Desktop Chromium'], 18 | headless: false, 19 | }, 20 | }, 21 | /* 22 | { 23 | name: 'Firefox', 24 | use: { 25 | ...devices['Desktop Firefox'], 26 | headless: false, 27 | }, 28 | }, 29 | { 30 | name: 'Safari', 31 | use: { 32 | ...devices['Desktop Safari'], 33 | headless: false, 34 | }, 35 | }, 36 | */ 37 | ], 38 | }; 39 | -------------------------------------------------------------------------------- /local/config/src/resolve.json: -------------------------------------------------------------------------------- 1 | { 2 | "extensions": [".tsx", ".ts", ".jsx", ".js", ".json"], 3 | "styleExtensions": [".css", ".scss", ".sass"], 4 | "directories": ["node_modules"], 5 | "paths": { 6 | "rollupTypes": { 7 | "~/*": ["/*"] 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /local/config/src/vitest-coverage.js: -------------------------------------------------------------------------------- 1 | export const vitestCoverage = { 2 | coverageDirectory: './.coverage/unit', 3 | }; 4 | -------------------------------------------------------------------------------- /local/config/src/vitest-setup.dom.js: -------------------------------------------------------------------------------- 1 | import '@testing-library/jest-dom/vitest'; 2 | import { mockAnimationApi, mockComputedStyles } from './mocks.js'; 3 | 4 | mockAnimationApi(); 5 | mockComputedStyles(); 6 | -------------------------------------------------------------------------------- /local/config/src/vitest-setup.node.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KingSora/OverlayScrollbars/9cb3e2249f4be85e1e27753a85d20c00fc68cbda/local/config/src/vitest-setup.node.js -------------------------------------------------------------------------------- /local/config/src/vitest.js: -------------------------------------------------------------------------------- 1 | import { resolve } from 'node:path'; 2 | import { fileURLToPath } from 'url'; 3 | import { defineProject, defineConfig } from 'vitest/config'; 4 | import { vitestCoverage } from './vitest-coverage.js'; 5 | 6 | const testDirName = 'test'; 7 | const testFileSuffix = 'test'; 8 | const dirname = fileURLToPath(new URL('.', import.meta.url)); 9 | const getInclude = (environment) => [ 10 | `${testDirName}/${environment}/**/*.${testFileSuffix}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}`, 11 | ]; 12 | const shared = { 13 | poolOptions: { 14 | forks: { 15 | singleFork: true, 16 | }, 17 | }, 18 | }; 19 | 20 | export const vitestNodeProjectConfig = defineProject({ 21 | test: { 22 | name: 'node', 23 | setupFiles: resolve(dirname, 'vitest-setup.node.js'), 24 | include: getInclude('node'), 25 | environment: 'node', 26 | ...shared, 27 | }, 28 | }); 29 | 30 | export const vitestDomProjectConfig = defineProject({ 31 | test: { 32 | name: 'dom', 33 | setupFiles: resolve(dirname, 'vitest-setup.dom.js'), 34 | include: getInclude('dom'), 35 | environment: 'jsdom', 36 | ...shared, 37 | }, 38 | }); 39 | 40 | export const vitestConfig = defineConfig({ 41 | test: { 42 | coverage: { 43 | reportsDirectory: vitestCoverage.coverageDirectory, 44 | }, 45 | workspace: [vitestNodeProjectConfig, vitestDomProjectConfig], 46 | }, 47 | }); 48 | -------------------------------------------------------------------------------- /local/esbuild/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@~local/esbuild", 3 | "private": true, 4 | "sideEffects": false, 5 | "main": "src/esbuild.js", 6 | "type": "module" 7 | } 8 | -------------------------------------------------------------------------------- /local/esbuild/src/normalizePathSlashes.js: -------------------------------------------------------------------------------- 1 | const isExtendedLengthPath = /^\\\\\?\\/; 2 | 3 | export const normalizePathSlashes = (path) => 4 | isExtendedLengthPath.test(path) ? path : path.replace(/\\/g, '/'); 5 | -------------------------------------------------------------------------------- /local/esbuild/src/plugins/clearOldBuild.js: -------------------------------------------------------------------------------- 1 | import fs from 'node:fs'; 2 | import path from 'node:path'; 3 | 4 | export const esbuildClearOldBuild = () => { 5 | let cleared = false; 6 | return { 7 | name: 'clearOldBuild', 8 | setup(build) { 9 | const initBuildOptions = build.initialOptions; 10 | 11 | build.onStart(() => { 12 | if (!cleared && initBuildOptions.outdir) { 13 | fs.rmSync(path.resolve(initBuildOptions.outdir), { recursive: true, force: true }); 14 | cleared = true; 15 | } 16 | }); 17 | }, 18 | }; 19 | }; 20 | -------------------------------------------------------------------------------- /local/esbuild/src/plugins/external.js: -------------------------------------------------------------------------------- 1 | const externalRegex = /node_modules/; 2 | 3 | export const esbuildPluginExternal = () => ({ 4 | name: 'external', 5 | setup(build) { 6 | build.onResolve({ filter: /.*/, namespace: 'file' }, async (args) => { 7 | const { resolveDir, kind } = args; 8 | 9 | if (kind !== 'entry-point') { 10 | const { path: resolvedPath } = await build.resolve(args.path, { 11 | resolveDir, 12 | kind, 13 | namespace: 'resolve-pls', 14 | }); 15 | 16 | if (externalRegex.test(resolvedPath)) { 17 | return { 18 | path: args.path, 19 | external: true, 20 | }; 21 | } 22 | } 23 | }); 24 | }, 25 | }); 26 | -------------------------------------------------------------------------------- /local/esbuild/src/resolveConfig.js: -------------------------------------------------------------------------------- 1 | import url from 'node:url'; 2 | import path from 'node:path'; 3 | 4 | export const resolveConfig = async (configPath) => { 5 | if (configPath) { 6 | const loadedConfig = ( 7 | await import(url.pathToFileURL(path.resolve(configPath))).catch(() => ({})) 8 | ).default; 9 | if (loadedConfig) { 10 | return loadedConfig; 11 | } 12 | } 13 | }; 14 | -------------------------------------------------------------------------------- /local/esbuild/src/writeOnlyChanges.js: -------------------------------------------------------------------------------- 1 | import fs from 'node:fs'; 2 | import crypto from 'node:crypto'; 3 | import path from 'node:path'; 4 | 5 | const getHash = (content) => crypto.createHash('md5').update(content).digest('hex'); 6 | 7 | export const writeOnlyChanges = async (outputFiles, changesMap) => { 8 | await Promise.all( 9 | outputFiles.map(({ path: filepath }) => 10 | fs.promises.mkdir(path.dirname(filepath), { recursive: true }) 11 | ) 12 | ); 13 | await Promise.all( 14 | outputFiles.map(({ path: filepath, contents }) => { 15 | const currContentsHash = getHash(contents); 16 | const cacheHash = changesMap.get(filepath); 17 | 18 | if (cacheHash !== currContentsHash) { 19 | changesMap.set(filepath, currContentsHash); 20 | return fs.promises.writeFile(filepath, contents); 21 | } 22 | return null; 23 | }) 24 | ); 25 | }; 26 | -------------------------------------------------------------------------------- /local/full-coverage/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@~local/full-coverage", 3 | "private": true, 4 | "type": "module", 5 | "bin": { 6 | "full-coverage": "./bin/generateFullCoverage.js" 7 | }, 8 | "dependencies": { 9 | "nyc": "^15.1.0" 10 | }, 11 | "version": "0.0.0" 12 | } 13 | -------------------------------------------------------------------------------- /local/playwright-tooling/bin/mergeCoverage.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | import fs from 'node:fs'; 3 | import { execSync } from 'node:child_process'; 4 | import { join } from 'node:path'; 5 | import { playwrightCoverage } from '@~local/config/playwright-coverage'; 6 | 7 | const { coverageDirectory, tmpCoverageDirectory } = playwrightCoverage; 8 | 9 | const mergeCoverage = async () => { 10 | if (fs.existsSync(tmpCoverageDirectory)) { 11 | const mergeDestination = join(tmpCoverageDirectory, `merged_${Date.now()}.json`); 12 | execSync(`nyc merge ${tmpCoverageDirectory} ${mergeDestination}`); 13 | const files = fs.readdirSync(tmpCoverageDirectory); 14 | files.forEach((file) => { 15 | const filePath = join(tmpCoverageDirectory, file); 16 | if (filePath !== mergeDestination) { 17 | fs.rmSync(filePath); 18 | } 19 | }); 20 | 21 | execSync( 22 | `nyc report --reporter=lcov --reporter=text --reporter=clover --reporter=json --report-dir=${coverageDirectory} --temp-dir=${tmpCoverageDirectory}`, 23 | { stdio: 'inherit' } 24 | ); 25 | fs.rmSync(tmpCoverageDirectory, { recursive: true }); 26 | } 27 | }; 28 | 29 | (async () => { 30 | try { 31 | await mergeCoverage(); 32 | } catch (e) { 33 | console.error(`Playwright coverage couldn't be merged.`, e); 34 | 35 | if (fs.existsSync(tmpCoverageDirectory)) { 36 | fs.rmSync(tmpCoverageDirectory, { recursive: true }); 37 | } 38 | } 39 | })(); 40 | -------------------------------------------------------------------------------- /local/playwright-tooling/index.d.ts: -------------------------------------------------------------------------------- 1 | declare module '@~local/playwright-tooling' { 2 | export interface PlaywrightRollupOptions { 3 | useEsbuild?: boolean; 4 | adaptUrl?: (originalUrl: string) => string; 5 | } 6 | export function playwrightRollup(options?: PlaywrightRollupOptions): void; 7 | export function expectSuccess(page: any): Promise; 8 | } 9 | -------------------------------------------------------------------------------- /local/playwright-tooling/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@~local/playwright-tooling", 3 | "private": true, 4 | "type": "module", 5 | "main": "./src/index.js", 6 | "module": "./src/index.js", 7 | "bin": { 8 | "playwright-merge-coverage": "./bin/mergeCoverage.js" 9 | }, 10 | "dependencies": { 11 | "@rollup/plugin-html": "^1.0.3", 12 | "istanbul-lib-instrument": "^5.2.0", 13 | "rollup-plugin-livereload": "^2.0.0", 14 | "rollup-plugin-serve": "^2.0.0", 15 | "rollup-plugin-styles": "^4.0.0" 16 | }, 17 | "types": "index.d.ts", 18 | "version": "0.0.0" 19 | } 20 | -------------------------------------------------------------------------------- /local/playwright-tooling/src/collectCoverage.js: -------------------------------------------------------------------------------- 1 | import fs from 'node:fs'; 2 | import { basename, dirname, join } from 'node:path'; 3 | import { playwrightCoverage } from '@~local/config/playwright-coverage'; 4 | 5 | const { tmpCoverageDirectory } = playwrightCoverage; 6 | 7 | export default async (coverageOutputDir, coverage, testfile) => { 8 | if (coverage) { 9 | const coveragePath = join( 10 | coverageOutputDir, 11 | `${tmpCoverageDirectory}/${basename(dirname(testfile))}_${Date.now()}.json` 12 | ); 13 | fs.mkdirSync(dirname(coveragePath), { recursive: true }); 14 | fs.writeFileSync(coveragePath, coverage); 15 | } 16 | }; 17 | -------------------------------------------------------------------------------- /local/playwright-tooling/src/expectSuccess.js: -------------------------------------------------------------------------------- 1 | import { expect } from '@playwright/test'; 2 | 3 | const startSelector = '#start'; 4 | const resultSelector = '#testResult'; 5 | const logError = async (page, ...args) => { 6 | const title = await page.title(); 7 | 8 | console.log(title, ...args); 9 | }; 10 | 11 | // default timeout = // 15mins 12 | export default async (page, timeout = 10 * 60 * 1500) => { 13 | page.on('pageerror', (err) => { 14 | logError(page, err.message); 15 | }); 16 | page.on('console', (msg) => { 17 | if (msg.type() === 'error') { 18 | logError(page, msg.text()); 19 | } 20 | }); 21 | 22 | await page.waitForLoadState('domcontentloaded', { timeout: 5000 }); 23 | await page.click(startSelector, { timeout: 1000 }); 24 | await page.mouse.move(0, 0); 25 | 26 | await page.locator(resultSelector).waitFor({ state: 'visible', timeout }); 27 | await expect(page.locator(resultSelector)).toHaveClass('passed', { timeout: 1000 }); 28 | }; 29 | -------------------------------------------------------------------------------- /local/playwright-tooling/src/index.js: -------------------------------------------------------------------------------- 1 | export { default as playwrightRollup } from './playwrightRollup.js'; 2 | export { default as expectSuccess } from './expectSuccess.js'; 3 | -------------------------------------------------------------------------------- /local/playwright-tooling/src/rollup/rollupPlaywrightAdditionalWatchFilesPlugin.js: -------------------------------------------------------------------------------- 1 | import fs from 'node:fs'; 2 | 3 | export const rollupPlaywrightAdditionalWatchFilesPlugin = (files) => ({ 4 | buildStart() { 5 | if (files) { 6 | files.forEach((file) => { 7 | if (fs.existsSync(file)) { 8 | this.addWatchFile(file); 9 | } 10 | }); 11 | } 12 | }, 13 | }); 14 | -------------------------------------------------------------------------------- /local/playwright-tooling/src/rollup/rollupPlaywrightIstanbulPlugin.js: -------------------------------------------------------------------------------- 1 | import { createFilter } from '@rollup/pluginutils'; 2 | import istanbul from 'istanbul-lib-instrument'; 3 | 4 | export const rollupPlaywrightIstanbulPlugin = (options = {}) => { 5 | const filter = createFilter(options.include, options.exclude); 6 | 7 | return { 8 | name: 'istanbul', 9 | transform(code, id) { 10 | if (!filter(id)) { 11 | return; 12 | } 13 | 14 | const instrumenter = istanbul.createInstrumenter({ 15 | esModules: true, 16 | compact: true, 17 | produceSourceMap: true, 18 | autoWrap: true, 19 | preserveComments: true, 20 | ...options.instrumenterConfig, 21 | }); 22 | 23 | const combinedSourceMap = this.getCombinedSourcemap(); 24 | const instrumentedCode = instrumenter.instrumentSync(code, id, { 25 | ...combinedSourceMap, 26 | version: String(combinedSourceMap.version), 27 | }); 28 | const sourceMap = instrumenter.lastSourceMap(); 29 | 30 | return { code: instrumentedCode, map: { ...sourceMap, version: Number(sourceMap.version) } }; 31 | }, 32 | }; 33 | }; 34 | -------------------------------------------------------------------------------- /local/rollup/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@~local/rollup", 3 | "private": true, 4 | "type": "module", 5 | "dependencies": { 6 | "@rollup/plugin-babel": "^6.0.4", 7 | "@rollup/plugin-commonjs": "^25.0.7", 8 | "@rollup/plugin-node-resolve": "^15.2.3", 9 | "@rollup/plugin-terser": "^0.4.4", 10 | "@rollup/plugin-virtual": "^3.0.1", 11 | "autoprefixer": "^10.4.7", 12 | "cssnano": "^5.1.12", 13 | "glob": "^7.1.6", 14 | "postcss": "^8.4.14", 15 | "rollup-plugin-dts": "^5.3.1", 16 | "rollup-plugin-esbuild-resolve": "^1.0.0", 17 | "rollup-plugin-ignore-import": "^1.3.2", 18 | "rollup-plugin-license": "^3.2.0", 19 | "rollup-plugin-scss": "^3.0.0", 20 | "rollup-plugin-tsconfig-paths": "^1.5.2", 21 | "rollup-plugin-typescript2": "^0.32.1" 22 | }, 23 | "exports": { 24 | ".": "./src/createRollupConfig.js", 25 | "./plugin/rollupCopyPlugin": "./src/plugins/rollupCopyPlugin.js", 26 | "./plugin/rollupPackageJsonPlugin": "./src/plugins/rollupPackageJsonPlugin.js" 27 | }, 28 | "version": "0.0.0" 29 | } 30 | -------------------------------------------------------------------------------- /local/rollup/src/bundle/babel.config.es2015.js: -------------------------------------------------------------------------------- 1 | export default { 2 | assumptions: { 3 | arrayLikeIsIterable: true, 4 | constantReexports: true, 5 | constantSuper: true, 6 | ignoreFunctionLength: true, 7 | ignoreToPrimitiveHint: true, 8 | iterableIsArray: true, 9 | mutableTemplateObject: true, 10 | noClassCalls: true, 11 | noDocumentAll: true, 12 | noNewArrows: true, 13 | objectRestNoSymbols: true, 14 | privateFieldsAsProperties: true, 15 | privateFieldsAsSymbols: true, 16 | pureGetters: true, 17 | setClassMethods: true, 18 | setComputedProperties: true, 19 | setPublicClassFields: true, 20 | setSpreadProperties: true, 21 | }, 22 | presets: [ 23 | [ 24 | '@babel/preset-env', 25 | { 26 | loose: true, 27 | bugfixes: true, 28 | targets: { 29 | esmodules: true, 30 | }, 31 | }, 32 | ], 33 | ], 34 | }; 35 | -------------------------------------------------------------------------------- /local/rollup/src/bundle/babel.config.es5.js: -------------------------------------------------------------------------------- 1 | export default { 2 | assumptions: { 3 | arrayLikeIsIterable: true, 4 | constantReexports: true, 5 | constantSuper: true, 6 | ignoreFunctionLength: true, 7 | ignoreToPrimitiveHint: true, 8 | iterableIsArray: true, 9 | mutableTemplateObject: true, 10 | noClassCalls: true, 11 | noDocumentAll: true, 12 | noNewArrows: true, 13 | objectRestNoSymbols: true, 14 | privateFieldsAsProperties: true, 15 | privateFieldsAsSymbols: true, 16 | pureGetters: true, 17 | setClassMethods: true, 18 | setComputedProperties: true, 19 | setPublicClassFields: true, 20 | setSpreadProperties: true, 21 | }, 22 | presets: [ 23 | [ 24 | '@babel/preset-env', 25 | { 26 | loose: true, 27 | targets: { 28 | firefox: '54', 29 | chrome: '58', 30 | ie: '11', 31 | esmodules: false, 32 | }, 33 | }, 34 | ], 35 | ], 36 | }; 37 | -------------------------------------------------------------------------------- /local/rollup/src/bundle/script.esbuild.js: -------------------------------------------------------------------------------- 1 | import path from 'node:path'; 2 | import buildPlugins from './plugins.js'; 3 | 4 | const { rollupEsBuild, rollupCommonjs, rollupEsbuildResolve, rollupScss, rollupLicense } = 5 | buildPlugins; 6 | 7 | export default (resolve, options) => { 8 | const { rollup, paths, extractStyles, banner } = options; 9 | const { output: rollupOutput, input, plugins = [], ...rollupOptions } = rollup; 10 | const { file, sourcemap: rawSourcemap, ...outputConfig } = rollupOutput; 11 | const { js: jsPath } = paths; 12 | const sourcemap = rawSourcemap; 13 | 14 | const output = { 15 | ...outputConfig, 16 | sourcemap, 17 | format: 'esm', 18 | generatedCode: 'es2015', 19 | file: path.resolve(jsPath, `${file}.js`), 20 | }; 21 | 22 | return { 23 | input, 24 | output, 25 | ...rollupOptions, 26 | plugins: [ 27 | rollupEsbuildResolve(resolve), 28 | rollupLicense(banner, sourcemap), 29 | rollupScss(resolve, sourcemap, extractStyles, false), 30 | rollupEsBuild(sourcemap), 31 | rollupCommonjs(sourcemap, resolve), 32 | ...plugins, 33 | ], 34 | }; 35 | }; 36 | -------------------------------------------------------------------------------- /local/rollup/src/bundle/styles.js: -------------------------------------------------------------------------------- 1 | import path from 'node:path'; 2 | import buildPlugins from './plugins.js'; 3 | 4 | const { rollupEsbuildResolve, rollupScss, rollupEsBuild } = buildPlugins; 5 | 6 | export default (resolve, options) => { 7 | const { rollup, paths, banner, extractStyles } = options; 8 | const { output: rollupOutput, input } = rollup; 9 | const { file, sourcemap } = rollupOutput; 10 | const { styles: stylesPath } = paths; 11 | const ogWrite = process.stdout.write; 12 | 13 | const pipeline = (cssFilename, minified) => ({ 14 | input, 15 | external: (id, parentId) => { 16 | if (!parentId) { 17 | return false; 18 | } 19 | return !resolve.styleExtensions.find((ext) => id.endsWith(ext)); 20 | }, 21 | plugins: [ 22 | rollupEsbuildResolve(resolve), 23 | rollupScss( 24 | resolve, 25 | false && sourcemap && !minified, 26 | extractStyles, 27 | path.resolve(stylesPath, cssFilename), 28 | banner, 29 | minified 30 | ), 31 | rollupEsBuild(false), 32 | { 33 | generateBundle() { 34 | process.stdout.write = () => { 35 | process.stdout.write = ogWrite; 36 | }; 37 | }, 38 | writeBundle() { 39 | process.stdout.write = ogWrite; 40 | }, 41 | }, 42 | ], 43 | }); 44 | 45 | return [pipeline(`${file}.css`), pipeline(`${file}.min.css`, true)]; 46 | }; 47 | -------------------------------------------------------------------------------- /local/rollup/src/defaultOptions.js: -------------------------------------------------------------------------------- 1 | export default { 2 | project: null, 3 | verbose: false, 4 | banner: null, 5 | useEsbuild: false, 6 | outDir: './dist', 7 | clean: false, 8 | copy: false, 9 | paths: { 10 | js: '.', 11 | types: './types', 12 | styles: './styles', 13 | }, 14 | versions: [ 15 | { 16 | format: 'cjs', 17 | generatedCode: 'es2015', 18 | extension: '.cjs.js', 19 | minifiedVersion: true, 20 | }, 21 | { 22 | format: 'esm', 23 | generatedCode: 'es2015', 24 | extension: '.esm.js', 25 | minifiedVersion: true, 26 | }, 27 | ], 28 | extractStyles: false, 29 | extractTypes: false, 30 | extractPackageJson: false, 31 | alias: {}, 32 | rollup: { 33 | input: './src/index', 34 | output: { 35 | sourcemap: false, 36 | exports: 'auto', 37 | }, 38 | }, 39 | }; 40 | -------------------------------------------------------------------------------- /local/rollup/src/pipeline.default.js: -------------------------------------------------------------------------------- 1 | import bundleScriptDefault from './bundle/script.default.js'; 2 | import bundleScriptEsbuild from './bundle/script.esbuild.js'; 3 | import bundleStyles from './bundle/styles.js'; 4 | import bundleTypes from './bundle/types.js'; 5 | import preBuild from './bundle/pre.js'; 6 | 7 | export default (resolve, options, esbuild) => { 8 | const { extractTypes, extractStyles } = options; 9 | const bundleScript = esbuild ? bundleScriptEsbuild : bundleScriptDefault; 10 | 11 | const pre = preBuild(resolve, options); 12 | const styles = extractStyles && bundleStyles(resolve, options); 13 | const types = extractTypes && bundleTypes(resolve, options); 14 | const js = bundleScript(resolve, options); 15 | 16 | return [pre, styles, types, js].flat().filter((build) => !!build); 17 | }; 18 | -------------------------------------------------------------------------------- /local/rollup/src/plugins/rollupAdditionalWatchFilesPlugin.js: -------------------------------------------------------------------------------- 1 | import fs from 'node:fs'; 2 | 3 | export const rollupAdditionalWatchFilesPlugin = (files) => ({ 4 | buildStart() { 5 | if (files) { 6 | files.forEach((file) => { 7 | if (fs.existsSync(file)) { 8 | this.addWatchFile(file); 9 | } 10 | }); 11 | } 12 | }, 13 | }); 14 | -------------------------------------------------------------------------------- /local/rollup/src/plugins/rollupCleanPlugin.js: -------------------------------------------------------------------------------- 1 | import path from 'node:path'; 2 | import fs from 'node:fs'; 3 | 4 | export const rollupCleanPlugin = ({ paths = [], verbose = false } = {}) => { 5 | let cleaned = false; 6 | return { 7 | name: 'clean', 8 | buildStart() { 9 | if (!cleaned) { 10 | paths.forEach((currPath) => { 11 | const resolvedPath = path.resolve(currPath); 12 | if (fs.existsSync(resolvedPath)) { 13 | if (verbose) { 14 | // eslint-disable-next-line no-console 15 | console.log(`Clean: ${resolvedPath}`); 16 | } 17 | fs.rmSync(resolvedPath, { recursive: true }); 18 | } 19 | }); 20 | cleaned = true; 21 | } 22 | }, 23 | }; 24 | }; 25 | -------------------------------------------------------------------------------- /local/rollup/src/plugins/rollupCopyPlugin.js: -------------------------------------------------------------------------------- 1 | import path from 'node:path'; 2 | import fs from 'node:fs'; 3 | 4 | export const rollupCopyPlugin = ({ paths = [], verbose = false } = {}) => { 5 | return { 6 | name: 'copy', 7 | buildStart() { 8 | paths.forEach((currPath) => { 9 | const resolvedPath = path.resolve(currPath); 10 | 11 | if (fs.existsSync(resolvedPath)) { 12 | if (verbose) { 13 | // eslint-disable-next-line no-console 14 | console.log(`Copy: ${resolvedPath}`); 15 | } 16 | this.emitFile({ 17 | type: 'asset', 18 | source: fs.readFileSync(resolvedPath), 19 | fileName: path.basename(resolvedPath), 20 | }); 21 | } 22 | }); 23 | }, 24 | }; 25 | }; 26 | -------------------------------------------------------------------------------- /local/rollup/src/plugins/rollupEsbuildPlugin.js: -------------------------------------------------------------------------------- 1 | import { extname } from 'node:path'; 2 | import { transform } from 'esbuild'; 3 | import { createFilter } from '@rollup/pluginutils'; 4 | 5 | const defaultLoader = { 6 | '.js': 'js', 7 | '.jsx': 'jsx', 8 | '.ts': 'ts', 9 | '.tsx': 'tsx', 10 | }; 11 | 12 | export const rollupEsbuildPlugin = ({ include, exclude, ...esbuildOptions } = {}) => { 13 | const extensions = Object.keys(defaultLoader); 14 | const INCLUDE_REGEXP = new RegExp(`\\.(${extensions.map((ext) => ext.slice(1)).join('|')})$`); 15 | const EXCLUDE_REGEXP = /node_modules/; 16 | const filter = createFilter(include || INCLUDE_REGEXP, exclude || EXCLUDE_REGEXP); 17 | 18 | return { 19 | name: 'esbuild', 20 | async transform(code, id) { 21 | if (!filter(id)) { 22 | return null; 23 | } 24 | 25 | const ext = extname(id); 26 | const loader = defaultLoader[ext]; 27 | 28 | if (!loader) { 29 | return null; 30 | } 31 | 32 | const result = await transform(code, { 33 | sourcefile: id, 34 | loader, 35 | ...esbuildOptions, 36 | }); 37 | 38 | return ( 39 | result.code && { 40 | code: result.code, 41 | map: result.map || null, 42 | } 43 | ); 44 | }, 45 | }; 46 | }; 47 | -------------------------------------------------------------------------------- /local/rollup/src/plugins/rollupPackageJsonPlugin.js: -------------------------------------------------------------------------------- 1 | import path from 'node:path'; 2 | import { pathToFileURL } from 'node:url'; 3 | 4 | export const rollupPackageJsonPlugin = ({ 5 | input = 'package.json', 6 | output = 'package.json', 7 | json, 8 | } = {}) => { 9 | const resolvedInput = path.resolve(input); 10 | 11 | return { 12 | name: 'packageJson', 13 | async buildStart() { 14 | const inputPackageJson = ( 15 | await import(pathToFileURL(resolvedInput), { 16 | with: { type: 'json' }, 17 | }) 18 | ).default; 19 | this.emitFile({ 20 | type: 'asset', 21 | source: JSON.stringify( 22 | typeof json === 'function' ? json(inputPackageJson) : inputPackageJson, 23 | null, 24 | 2 25 | ), 26 | fileName: output, 27 | }); 28 | }, 29 | }; 30 | }; 31 | -------------------------------------------------------------------------------- /local/tailwind/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@~local/tailwind", 3 | "private": true, 4 | "type": "module", 5 | "main": "tailwind.config.js", 6 | "devDependencies": { 7 | "@tailwindcss/typography": "^0.5.7" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /local/tsconfig/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@~local/tsconfig", 3 | "private": true, 4 | "type": "module", 5 | "main": "./tsconfig.json", 6 | "version": "0.0.0" 7 | } 8 | -------------------------------------------------------------------------------- /local/tsconfig/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "strict": true, 4 | "allowJs": false, 5 | "allowSyntheticDefaultImports": true, 6 | "esModuleInterop": true, 7 | "target": "ESNext", 8 | "sourceMap": true, 9 | "declaration": true, 10 | "module": "ESNext", 11 | "moduleResolution": "node", 12 | "removeComments": false 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /logo/logo.ai: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KingSora/OverlayScrollbars/9cb3e2249f4be85e1e27753a85d20c00fc68cbda/logo/logo.ai -------------------------------------------------------------------------------- /logo/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KingSora/OverlayScrollbars/9cb3e2249f4be85e1e27753a85d20c00fc68cbda/logo/logo.png -------------------------------------------------------------------------------- /packages/overlayscrollbars-ngx/.gitignore: -------------------------------------------------------------------------------- 1 | # See http://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # Compiled output 4 | /dist 5 | /tmp 6 | /out-tsc 7 | /bazel-out 8 | 9 | # Node 10 | /node_modules 11 | npm-debug.log 12 | yarn-error.log 13 | 14 | # IDEs and editors 15 | .idea/ 16 | .project 17 | .classpath 18 | .c9/ 19 | *.launch 20 | .settings/ 21 | *.sublime-workspace 22 | 23 | # Visual Studio Code 24 | .vscode/* 25 | !.vscode/settings.json 26 | !.vscode/tasks.json 27 | !.vscode/launch.json 28 | !.vscode/extensions.json 29 | .history/* 30 | 31 | # Miscellaneous 32 | /.angular 33 | /.angular/cache 34 | /.playwright 35 | .sass-cache/ 36 | /connect.lock 37 | /coverage 38 | /libpeerconnection.log 39 | testem.log 40 | /typings 41 | 42 | # System files 43 | .DS_Store 44 | Thumbs.db 45 | -------------------------------------------------------------------------------- /packages/overlayscrollbars-ngx/angular.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "./node_modules/@angular/cli/lib/config/schema.json", 3 | "version": 1, 4 | "newProjectRoot": ".", 5 | "projects": { 6 | "overlayscrollbars-ngx": { 7 | "projectType": "library", 8 | "root": "", 9 | "sourceRoot": "src", 10 | "prefix": "lib", 11 | "architect": { 12 | "build": { 13 | "builder": "@angular-devkit/build-angular:ng-packagr", 14 | "options": { 15 | "project": "ng-package.json" 16 | }, 17 | "configurations": { 18 | "production": { 19 | "tsConfig": "tsconfig.lib.prod.json" 20 | }, 21 | "development": { 22 | "tsConfig": "tsconfig.lib.json" 23 | } 24 | }, 25 | "defaultConfiguration": "production" 26 | }, 27 | "test": { 28 | "builder": "@angular-devkit/build-angular:karma", 29 | "options": { 30 | "main": "test/test.ts", 31 | "tsConfig": "tsconfig.spec.json", 32 | "karmaConfig": "karma.conf.js" 33 | } 34 | } 35 | } 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /packages/overlayscrollbars-ngx/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /packages/overlayscrollbars-ngx/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "./node_modules/ng-packagr/ng-package.schema.json", 3 | "dest": "./dist", 4 | "lib": { 5 | "entryFile": "src/public-api.ts" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /packages/overlayscrollbars-ngx/src/overlayscrollbars.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { OverlayScrollbarsDirective } from './overlayscrollbars.directive'; 3 | import { OverlayScrollbarsComponent } from './overlayscrollbars.component'; 4 | 5 | @NgModule({ 6 | declarations: [OverlayScrollbarsComponent, OverlayScrollbarsDirective], 7 | exports: [OverlayScrollbarsComponent, OverlayScrollbarsDirective], 8 | }) 9 | export class OverlayscrollbarsModule {} 10 | -------------------------------------------------------------------------------- /packages/overlayscrollbars-ngx/src/public-api.ts: -------------------------------------------------------------------------------- 1 | export * from './overlayscrollbars.component'; 2 | export * from './overlayscrollbars.directive'; 3 | export * from './overlayscrollbars.module'; 4 | -------------------------------------------------------------------------------- /packages/overlayscrollbars-ngx/test/test.ts: -------------------------------------------------------------------------------- 1 | // This file is required by karma.conf.js and loads recursively all the .spec and framework files 2 | 3 | import 'zone.js'; 4 | import 'zone.js/dist/zone-testing'; 5 | import { getTestBed } from '@angular/core/testing'; 6 | import { 7 | BrowserDynamicTestingModule, 8 | platformBrowserDynamicTesting, 9 | } from '@angular/platform-browser-dynamic/testing'; 10 | 11 | declare const require: { 12 | context( 13 | path: string, 14 | deep?: boolean, 15 | filter?: RegExp 16 | ): { 17 | (id: string): T; 18 | keys(): string[]; 19 | }; 20 | }; 21 | 22 | // First, initialize the Angular testing environment. 23 | getTestBed().initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting()); 24 | 25 | // Then we find all the tests. 26 | const context = require.context('./', true, /\.spec\.ts$/); 27 | // And load the modules. 28 | context.keys().forEach(context); 29 | -------------------------------------------------------------------------------- /packages/overlayscrollbars-ngx/tsconfig.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "compileOnSave": false, 4 | "compilerOptions": { 5 | "baseUrl": ".", 6 | "paths": { 7 | "~/*": ["./src/*"] 8 | }, 9 | "outDir": "./dist/out-tsc", 10 | "forceConsistentCasingInFileNames": true, 11 | "strict": true, 12 | "noImplicitReturns": true, 13 | "noFallthroughCasesInSwitch": true, 14 | "sourceMap": true, 15 | "declaration": false, 16 | "downlevelIteration": true, 17 | "experimentalDecorators": true, 18 | "moduleResolution": "node", 19 | "importHelpers": true, 20 | "target": "ES2015", 21 | "module": "es2020", 22 | "lib": ["ES2015", "dom"] 23 | }, 24 | "angularCompilerOptions": { 25 | "enableI18nLegacyMessageIdFormat": false, 26 | "strictInjectionParameters": true, 27 | "strictInputAccessModifiers": true, 28 | "strictTemplates": true 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /packages/overlayscrollbars-ngx/tsconfig.lib.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "extends": "./tsconfig.json", 4 | "compilerOptions": { 5 | "outDir": "./out-tsc/lib", 6 | "declaration": true, 7 | "declarationMap": true, 8 | "inlineSources": true, 9 | "types": [] 10 | }, 11 | "exclude": ["test/test.ts", "**/*.spec.ts"] 12 | } 13 | -------------------------------------------------------------------------------- /packages/overlayscrollbars-ngx/tsconfig.lib.prod.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "extends": "./tsconfig.lib.json", 4 | "compilerOptions": { 5 | "declarationMap": false 6 | }, 7 | "angularCompilerOptions": { 8 | "compilationMode": "partial" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /packages/overlayscrollbars-ngx/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "extends": "./tsconfig.json", 4 | "compilerOptions": { 5 | "outDir": "./out-tsc/spec", 6 | "skipLibCheck": true, 7 | "types": ["jasmine"] 8 | }, 9 | "files": ["test/test.ts"], 10 | "include": ["**/*.spec.ts", "**/*.d.ts"] 11 | } 12 | -------------------------------------------------------------------------------- /packages/overlayscrollbars-react/.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled output 2 | /dist 3 | 4 | # Node 5 | /node_modules 6 | 7 | # Miscellaneous 8 | /.coverage 9 | /.playwright 10 | -------------------------------------------------------------------------------- /packages/overlayscrollbars-react/src/overlayscrollbars-react.cts: -------------------------------------------------------------------------------- 1 | export * from './overlayscrollbars-react.js'; 2 | -------------------------------------------------------------------------------- /packages/overlayscrollbars-react/src/overlayscrollbars-react.mts: -------------------------------------------------------------------------------- 1 | export * from './overlayscrollbars-react.js'; 2 | -------------------------------------------------------------------------------- /packages/overlayscrollbars-react/src/overlayscrollbars-react.ts: -------------------------------------------------------------------------------- 1 | export * from './OverlayScrollbarsComponent'; 2 | export * from './useOverlayScrollbars'; 3 | -------------------------------------------------------------------------------- /packages/overlayscrollbars-react/test/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "jsx": "react-jsx", 5 | "types": ["@testing-library/jest-dom"] 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /packages/overlayscrollbars-react/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES6", 4 | "allowSyntheticDefaultImports": true, 5 | "lib": ["dom", "dom.iterable", "esnext"], 6 | "strict": true, 7 | "module": "ES2015", 8 | "moduleResolution": "node", 9 | "jsx": "preserve" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /packages/overlayscrollbars-react/tsconfig.types.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "rootDir": "./src/", 5 | "outDir": "./dist/types", 6 | "declaration": true 7 | }, 8 | "include": ["src/**/*"] 9 | } 10 | -------------------------------------------------------------------------------- /packages/overlayscrollbars-react/vitest.config.js: -------------------------------------------------------------------------------- 1 | import { mergeConfig } from 'vite'; 2 | import { vitestConfig } from '@~local/config/vitest'; 3 | import viteConfig from './vite.config.js'; 4 | 5 | export default mergeConfig(viteConfig, vitestConfig); 6 | -------------------------------------------------------------------------------- /packages/overlayscrollbars-solid/.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled output 2 | /dist 3 | 4 | # Node 5 | /node_modules 6 | 7 | # Miscellaneous 8 | /.coverage 9 | /.playwright 10 | -------------------------------------------------------------------------------- /packages/overlayscrollbars-solid/src/overlayscrollbars-solid.cts: -------------------------------------------------------------------------------- 1 | export * from './overlayscrollbars-solid.js'; 2 | -------------------------------------------------------------------------------- /packages/overlayscrollbars-solid/src/overlayscrollbars-solid.mts: -------------------------------------------------------------------------------- 1 | export * from './overlayscrollbars-solid.js'; 2 | -------------------------------------------------------------------------------- /packages/overlayscrollbars-solid/src/overlayscrollbars-solid.ts: -------------------------------------------------------------------------------- 1 | export * from './OverlayScrollbarsComponent'; 2 | export * from './createOverlayScrollbars'; 3 | -------------------------------------------------------------------------------- /packages/overlayscrollbars-solid/test/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "types": ["@testing-library/jest-dom"] 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /packages/overlayscrollbars-solid/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@~local/tsconfig", 3 | "compilerOptions": { 4 | "strict": true, 5 | "target": "ESNext", 6 | "module": "ESNext", 7 | "moduleResolution": "node", 8 | "allowSyntheticDefaultImports": true, 9 | "esModuleInterop": true, 10 | "jsx": "preserve", 11 | "jsxImportSource": "solid-js", 12 | "isolatedModules": true 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /packages/overlayscrollbars-solid/vitest.config.js: -------------------------------------------------------------------------------- 1 | import { mergeConfig } from 'vite'; 2 | import { vitestDomProjectConfig, vitestConfig } from '@~local/config/vitest'; 3 | import viteConfig from './vite.config.js'; 4 | 5 | export default mergeConfig( 6 | { 7 | ...viteConfig, 8 | resolve: { 9 | conditions: ['development', 'browser'], 10 | }, 11 | }, 12 | { 13 | ...vitestConfig, 14 | test: { 15 | ...vitestConfig.test, 16 | ...vitestDomProjectConfig.test, 17 | // workspaces don't work well with vite-plugin-solid 18 | workspace: undefined, 19 | }, 20 | } 21 | ); 22 | -------------------------------------------------------------------------------- /packages/overlayscrollbars-svelte/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /build 4 | /.svelte-kit 5 | /dist 6 | /.playwright 7 | .env 8 | .env.* 9 | !.env.example 10 | -------------------------------------------------------------------------------- /packages/overlayscrollbars-svelte/env.d.ts: -------------------------------------------------------------------------------- 1 | declare module '*.svelte' { 2 | const svelte: any; 3 | export default svelte; 4 | } 5 | -------------------------------------------------------------------------------- /packages/overlayscrollbars-svelte/src/overlayscrollbars-svelte.cts: -------------------------------------------------------------------------------- 1 | export * from './overlayscrollbars-svelte.js'; 2 | -------------------------------------------------------------------------------- /packages/overlayscrollbars-svelte/src/overlayscrollbars-svelte.mts: -------------------------------------------------------------------------------- 1 | export * from './overlayscrollbars-svelte.js'; 2 | -------------------------------------------------------------------------------- /packages/overlayscrollbars-svelte/src/overlayscrollbars-svelte.ts: -------------------------------------------------------------------------------- 1 | export { default as OverlayScrollbarsComponent } from './OverlayScrollbarsComponent.svelte'; 2 | export * from './OverlayScrollbarsComponent.types'; 3 | export * from './useOverlayScrollbars.svelte'; 4 | -------------------------------------------------------------------------------- /packages/overlayscrollbars-svelte/svelte.config.js: -------------------------------------------------------------------------------- 1 | import { sveltePreprocess } from 'svelte-preprocess'; 2 | 3 | /** @type {import('@sveltejs/kit').Config} */ 4 | const config = { 5 | // Consult https://github.com/sveltejs/svelte-preprocess 6 | // for more information about preprocessors 7 | preprocess: sveltePreprocess({ sourceMap: true }), 8 | compilerOptions: { 9 | enableSourcemap: true, 10 | }, 11 | }; 12 | 13 | export default config; 14 | -------------------------------------------------------------------------------- /packages/overlayscrollbars-svelte/test/dom/TestComponentBody.svelte: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 |
9 |
10 | -------------------------------------------------------------------------------- /packages/overlayscrollbars-svelte/test/dom/TestElement.svelte: -------------------------------------------------------------------------------- 1 | 7 | 8 |
9 | {@render children?.()} 10 |
11 | -------------------------------------------------------------------------------- /packages/overlayscrollbars-svelte/test/dom/TestUseOverlayScrollbarsInitialize.svelte: -------------------------------------------------------------------------------- 1 | 22 | 23 | 30 | -------------------------------------------------------------------------------- /packages/overlayscrollbars-svelte/test/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "types": ["@testing-library/jest-dom"] 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /packages/overlayscrollbars-svelte/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./.svelte-kit/tsconfig.json", 3 | "compilerOptions": { 4 | "allowJs": true, 5 | "checkJs": true, 6 | "esModuleInterop": true, 7 | "forceConsistentCasingInFileNames": true, 8 | "resolveJsonModule": true, 9 | "skipLibCheck": true, 10 | "sourceMap": true, 11 | "strict": true, 12 | "noEmit": true 13 | }, 14 | "include": ["**/*.ts", "**/*.mts", "**/*.cts", "**/*.d.ts"] 15 | } 16 | -------------------------------------------------------------------------------- /packages/overlayscrollbars-svelte/vitest.config.js: -------------------------------------------------------------------------------- 1 | import { mergeConfig } from 'vite'; 2 | import { vitestConfig, vitestDomProjectConfig } from '@~local/config/vitest'; 3 | import viteConfig from './vite.config.js'; 4 | 5 | export default mergeConfig( 6 | { 7 | ...viteConfig, 8 | // see https://github.com/testing-library/svelte-testing-library/issues/222 9 | resolve: { 10 | conditions: ['browser'], 11 | }, 12 | }, 13 | { 14 | ...vitestConfig, 15 | test: { 16 | ...vitestConfig.test, 17 | ...vitestDomProjectConfig.test, 18 | // workspaces don't work well with vite-plugin-svelte 19 | workspace: undefined, 20 | }, 21 | } 22 | ); 23 | -------------------------------------------------------------------------------- /packages/overlayscrollbars-vue/.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled output 2 | /dist 3 | 4 | # Node 5 | /node_modules 6 | 7 | # Miscellaneous 8 | /.coverage 9 | /.playwright -------------------------------------------------------------------------------- /packages/overlayscrollbars-vue/env.d.ts: -------------------------------------------------------------------------------- 1 | declare module '*.vue' { 2 | const vue: any; 3 | export default vue; 4 | } 5 | -------------------------------------------------------------------------------- /packages/overlayscrollbars-vue/logo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/overlayscrollbars-vue/src/OverlayScrollbarsComponent.types.ts: -------------------------------------------------------------------------------- 1 | import type { OverlayScrollbars, PartialOptions, EventListeners } from 'overlayscrollbars'; 2 | import type { Component } from 'vue'; 3 | 4 | export interface OverlayScrollbarsComponentProps { 5 | /** Tag of the root element. */ 6 | element?: string | Component; 7 | /** OverlayScrollbars options. */ 8 | options?: PartialOptions | false | null; 9 | /** OverlayScrollbars events. */ 10 | events?: EventListeners | false | null; 11 | /** Whether to defer the initialization to a point in time when the browser is idle. (or to the next frame if `window.requestIdleCallback` is not supported) */ 12 | defer?: boolean | IdleRequestOptions; 13 | } 14 | 15 | export interface OverlayScrollbarsComponentRef { 16 | /** Returns the OverlayScrollbars instance or null if not initialized. */ 17 | osInstance(): OverlayScrollbars | null; 18 | /** Returns the root element. */ 19 | getElement(): HTMLElement | null; 20 | } 21 | -------------------------------------------------------------------------------- /packages/overlayscrollbars-vue/src/overlayscrollbars-vue.cts: -------------------------------------------------------------------------------- 1 | export * from './overlayscrollbars-vue.js'; 2 | -------------------------------------------------------------------------------- /packages/overlayscrollbars-vue/src/overlayscrollbars-vue.mts: -------------------------------------------------------------------------------- 1 | export * from './overlayscrollbars-vue.js'; 2 | -------------------------------------------------------------------------------- /packages/overlayscrollbars-vue/src/overlayscrollbars-vue.ts: -------------------------------------------------------------------------------- 1 | export { default as OverlayScrollbarsComponent } from './OverlayScrollbarsComponent.vue'; 2 | export * from './OverlayScrollbarsComponent.types'; 3 | export * from './useOverlayScrollbars'; 4 | -------------------------------------------------------------------------------- /packages/overlayscrollbars-vue/test/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "types": ["@testing-library/jest-dom"] 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /packages/overlayscrollbars-vue/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@vue/tsconfig/tsconfig.json" 3 | } -------------------------------------------------------------------------------- /packages/overlayscrollbars-vue/tsconfig.types.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "rootDir": "./src/", 5 | "outDir": "./dist/types", 6 | "declaration": true 7 | }, 8 | "include": ["src/**/*"] 9 | } -------------------------------------------------------------------------------- /packages/overlayscrollbars-vue/vitest.config.js: -------------------------------------------------------------------------------- 1 | import { mergeConfig } from 'vite'; 2 | import { vitestConfig, vitestDomProjectConfig } from '@~local/config/vitest'; 3 | import viteConfig from './vite.config.js'; 4 | 5 | export default mergeConfig(viteConfig, { 6 | ...vitestConfig, 7 | test: { 8 | ...vitestConfig.test, 9 | ...vitestDomProjectConfig.test, 10 | // workspaces don't work well with vite-plugin-vue 11 | workspace: undefined, 12 | }, 13 | }); 14 | -------------------------------------------------------------------------------- /packages/overlayscrollbars/.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled output 2 | /dist 3 | 4 | # Tests generated output 5 | .build/ 6 | .fixtures/ 7 | .playwright/ 8 | 9 | # Node 10 | /node_modules 11 | 12 | -------------------------------------------------------------------------------- /packages/overlayscrollbars/globals.d.ts: -------------------------------------------------------------------------------- 1 | declare module '*.css' { 2 | const content: string; 3 | export default content; 4 | } 5 | 6 | declare module '*.scss' { 7 | const content: string; 8 | export default content; 9 | } 10 | 11 | declare module '*.html' { 12 | const content: string; 13 | export default content; 14 | } 15 | -------------------------------------------------------------------------------- /packages/overlayscrollbars/playwright.config.js: -------------------------------------------------------------------------------- 1 | export { default } from '@~local/config/playwright'; 2 | -------------------------------------------------------------------------------- /packages/overlayscrollbars/src/index.scss: -------------------------------------------------------------------------------- 1 | @use './styles/sizeobserver.scss'; 2 | @use './styles/trinsicobserver.scss'; 3 | @use './styles/structure.scss'; 4 | @use './styles/scrollbars.scss'; 5 | @use './styles/themes.scss'; 6 | -------------------------------------------------------------------------------- /packages/overlayscrollbars/src/index.ts: -------------------------------------------------------------------------------- 1 | import './index.scss'; 2 | 3 | export { 4 | Environment, 5 | OverlayScrollbars, 6 | Elements, 7 | State, 8 | CloneableScrollbarElements, 9 | ScrollbarElements, 10 | } from './overlayscrollbars'; 11 | export { ScrollbarsHidingPlugin, SizeObserverPlugin, ClickScrollPlugin } from './plugins'; 12 | 13 | export type { 14 | Options, 15 | PartialOptions, 16 | ReadonlyOptions, 17 | OverflowBehavior, 18 | ScrollbarsVisibilityBehavior, 19 | ScrollbarsAutoHideBehavior, 20 | } from './options'; 21 | export type { 22 | EventListener, 23 | EventListeners, 24 | EventListenerArgs, 25 | OnUpdatedEventListenerArgs, 26 | } from './eventListeners'; 27 | export type { 28 | Initialization, 29 | PartialInitialization, 30 | InitializationTarget, 31 | InitializationTargetElement, 32 | InitializationTargetObject, 33 | StaticInitialization, 34 | DynamicInitialization, 35 | StaticInitializationElement, 36 | DynamicInitializationElement, 37 | } from './initialization'; 38 | export type { 39 | PluginModuleInstance, 40 | PluginModule, 41 | Plugin, 42 | StaticPlugin, 43 | InstancePlugin, 44 | InstancePluginEvent, 45 | InferStaticPluginModuleInstance, 46 | InferInstancePluginModuleInstance, 47 | } from './plugins'; 48 | -------------------------------------------------------------------------------- /packages/overlayscrollbars/src/instances.ts: -------------------------------------------------------------------------------- 1 | import type { OverlayScrollbars } from './overlayscrollbars'; 2 | 3 | const targetInstanceMap: WeakMap = new WeakMap(); 4 | 5 | /** 6 | * Adds the given OverlayScrollbars instance to the given element. 7 | * @param target The element which is the target of the OverlayScrollbars instance. 8 | * @param osInstance The OverlayScrollbars instance. 9 | */ 10 | export const addInstance = (target: Element, osInstance: OverlayScrollbars): void => { 11 | targetInstanceMap.set(target, osInstance); 12 | }; 13 | 14 | /** 15 | * Removes a OverlayScrollbars instance from the given element. 16 | * @param target The element from which its OverlayScrollbars instance shall be removed. 17 | */ 18 | export const removeInstance = (target: Element): void => { 19 | targetInstanceMap.delete(target); 20 | }; 21 | 22 | /** 23 | * Gets the OverlayScrollbars from the given element or undefined if it doesn't have one. 24 | * @param target The element of which its OverlayScrollbars instance shall be get. 25 | */ 26 | export const getInstance = (target: Element): OverlayScrollbars | undefined => 27 | targetInstanceMap.get(target); 28 | -------------------------------------------------------------------------------- /packages/overlayscrollbars/src/nonce.ts: -------------------------------------------------------------------------------- 1 | let nonce: string | undefined; 2 | 3 | export const getNonce = () => nonce; 4 | export const setNonce = (newNonce: string | undefined) => { 5 | nonce = newNonce; 6 | }; 7 | -------------------------------------------------------------------------------- /packages/overlayscrollbars/src/observers/index.ts: -------------------------------------------------------------------------------- 1 | export * from './domObserver'; 2 | export * from './sizeObserver'; 3 | export * from './trinsicObserver'; 4 | -------------------------------------------------------------------------------- /packages/overlayscrollbars/src/plugins/clickScrollPlugin/index.ts: -------------------------------------------------------------------------------- 1 | export * from './clickScrollPlugin'; 2 | -------------------------------------------------------------------------------- /packages/overlayscrollbars/src/plugins/index.ts: -------------------------------------------------------------------------------- 1 | export * from './plugins'; 2 | export * from './optionsValidationPlugin'; 3 | export * from './sizeObserverPlugin'; 4 | export * from './scrollbarsHidingPlugin'; 5 | export * from './clickScrollPlugin'; 6 | -------------------------------------------------------------------------------- /packages/overlayscrollbars/src/plugins/optionsValidationPlugin/index.ts: -------------------------------------------------------------------------------- 1 | export * from './optionsValidationPlugin'; 2 | -------------------------------------------------------------------------------- /packages/overlayscrollbars/src/plugins/scrollbarsHidingPlugin/index.ts: -------------------------------------------------------------------------------- 1 | export * from './scrollbarsHidingPlugin'; 2 | -------------------------------------------------------------------------------- /packages/overlayscrollbars/src/plugins/sizeObserverPlugin/index.ts: -------------------------------------------------------------------------------- 1 | export * from './sizeObserverPlugin'; 2 | -------------------------------------------------------------------------------- /packages/overlayscrollbars/src/setups/index.ts: -------------------------------------------------------------------------------- 1 | export * from './setups'; 2 | export * from './observersSetup'; 3 | export * from './structureSetup'; 4 | export * from './scrollbarsSetup'; 5 | -------------------------------------------------------------------------------- /packages/overlayscrollbars/src/setups/observersSetup/index.ts: -------------------------------------------------------------------------------- 1 | export * from './observersSetup'; 2 | -------------------------------------------------------------------------------- /packages/overlayscrollbars/src/setups/scrollbarsSetup/index.ts: -------------------------------------------------------------------------------- 1 | export * from './scrollbarsSetup'; 2 | -------------------------------------------------------------------------------- /packages/overlayscrollbars/src/setups/structureSetup/index.ts: -------------------------------------------------------------------------------- 1 | export * from './structureSetup'; 2 | -------------------------------------------------------------------------------- /packages/overlayscrollbars/src/setups/structureSetup/updateSegments/index.ts: -------------------------------------------------------------------------------- 1 | export * from './trinsicUpdateSegment'; 2 | export * from './paddingUpdateSegment'; 3 | export * from './overflowUpdateSegment'; 4 | -------------------------------------------------------------------------------- /packages/overlayscrollbars/src/setups/structureSetup/updateSegments/trinsicUpdateSegment.ts: -------------------------------------------------------------------------------- 1 | import type { CreateStructureUpdateSegment } from '../structureSetup'; 2 | import { setStyles, strHeight } from '../../../support'; 3 | 4 | /** 5 | * Lifecycle with the responsibility to adjust the trinsic behavior of the content element. 6 | * @param structureUpdateHub 7 | * @returns 8 | */ 9 | export const createTrinsicUpdateSegment: CreateStructureUpdateSegment = 10 | ({ _content }) => 11 | ({ _observersUpdateHints, _observersState, _force }) => { 12 | const { _heightIntrinsicChanged } = _observersUpdateHints || {}; 13 | const { _heightIntrinsic } = _observersState; 14 | const heightIntrinsicChanged = _content && (_heightIntrinsicChanged || _force); 15 | 16 | if (heightIntrinsicChanged) { 17 | setStyles(_content, { 18 | [strHeight]: _heightIntrinsic && '100%', 19 | }); 20 | } 21 | }; 22 | -------------------------------------------------------------------------------- /packages/overlayscrollbars/src/styles/trinsicobserver.scss: -------------------------------------------------------------------------------- 1 | .os-trinsic-observer { 2 | flex: none; 3 | box-sizing: border-box; 4 | position: relative; 5 | max-width: 0px; 6 | max-height: 1px; 7 | padding: 0; 8 | margin: 0; 9 | border: none; 10 | overflow: hidden; 11 | z-index: -1; 12 | height: 0; 13 | top: calc(100% + 1px); 14 | contain: strict; 15 | 16 | &:not(:empty) { 17 | height: calc(100% + 1px); 18 | top: -1px; 19 | 20 | & > .os-size-observer { 21 | width: 1000%; 22 | height: 1000%; 23 | min-height: 1px; 24 | min-width: 1px; 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /packages/overlayscrollbars/src/support/compatibility/apis.ts: -------------------------------------------------------------------------------- 1 | import { wnd } from '../utils/alias'; 2 | 3 | const getApi = (name: string) => 4 | (typeof wnd[name as keyof typeof wnd] !== 'undefined' 5 | ? wnd[name as keyof typeof wnd] 6 | : undefined) as T; 7 | 8 | export const MutationObserverConstructor = getApi('MutationObserver'); 9 | export const IntersectionObserverConstructor = 10 | getApi('IntersectionObserver'); 11 | export const ResizeObserverConstructor = getApi('ResizeObserver'); 12 | export const scrollT = getApi AnimationTimeline>('ScrollTimeline'); 13 | -------------------------------------------------------------------------------- /packages/overlayscrollbars/src/support/compatibility/index.ts: -------------------------------------------------------------------------------- 1 | export * from './apis'; 2 | export * from './isBrowser'; 3 | -------------------------------------------------------------------------------- /packages/overlayscrollbars/src/support/compatibility/isBrowser.ts: -------------------------------------------------------------------------------- 1 | export const isBrowser = 2 | // deno has the global `window` defined 3 | typeof window !== 'undefined' && 4 | // make sure HTML element is available 5 | typeof HTMLElement !== 'undefined' && 6 | // make sure document is defined 7 | !!window.document; 8 | -------------------------------------------------------------------------------- /packages/overlayscrollbars/src/support/dom/create.ts: -------------------------------------------------------------------------------- 1 | import { each } from '../utils/array'; 2 | import { setAttrs } from './attribute'; 3 | import { contents } from './traversal'; 4 | import { removeElements } from './manipulation'; 5 | import { getTrustedTypePolicy } from '../../trustedTypePolicy'; 6 | 7 | /** 8 | * Creates a div DOM node. 9 | */ 10 | export const createDiv = (classNames?: string): HTMLDivElement => { 11 | const div = document.createElement('div'); 12 | setAttrs(div, 'class', classNames); 13 | return div; 14 | }; 15 | 16 | /** 17 | * Creates DOM nodes modeled after the passed html string and returns the root dom nodes as a array. 18 | * @param html The html string after which the DOM nodes shall be created. 19 | */ 20 | export const createDOM = (html: string): ReadonlyArray => { 21 | const createdDiv = createDiv(); 22 | const trustedTypesPolicy = getTrustedTypePolicy(); 23 | const trimmedHtml = html.trim(); 24 | createdDiv.innerHTML = trustedTypesPolicy 25 | ? // eslint-disable-next-line @typescript-eslint/no-explicit-any 26 | (trustedTypesPolicy as any).createHTML(trimmedHtml) 27 | : trimmedHtml; 28 | 29 | return each(contents(createdDiv), (elm) => removeElements(elm)); 30 | }; 31 | -------------------------------------------------------------------------------- /packages/overlayscrollbars/src/support/dom/focus.ts: -------------------------------------------------------------------------------- 1 | import type { NodeElementTarget } from './types'; 2 | 3 | export const focusElement = (element: NodeElementTarget) => { 4 | if (element && (element as HTMLElement).focus) { 5 | (element as HTMLElement).focus({ preventScroll: true }); 6 | } 7 | }; 8 | -------------------------------------------------------------------------------- /packages/overlayscrollbars/src/support/dom/index.ts: -------------------------------------------------------------------------------- 1 | export * from './attribute'; 2 | export * from './class'; 3 | export * from './create'; 4 | export * from './dimensions'; 5 | export * from './events'; 6 | export * from './style'; 7 | export * from './manipulation'; 8 | export * from './offset'; 9 | export * from './traversal'; 10 | export * from './scroll'; 11 | export * from './focus'; 12 | -------------------------------------------------------------------------------- /packages/overlayscrollbars/src/support/dom/manipulation.ts: -------------------------------------------------------------------------------- 1 | import type { NodeElementTarget, NodeElementTargetCollection } from './types'; 2 | import { createOrKeepArray, each } from '../utils/array'; 3 | import { parent } from './traversal'; 4 | import { bind } from '../utils'; 5 | 6 | /** 7 | * Removes the given Nodes from their parent. 8 | * @param nodes The Nodes which shall be removed. 9 | */ 10 | export const removeElements = (nodes: NodeElementTargetCollection): void => { 11 | each(createOrKeepArray(nodes), (node) => { 12 | const parentElm = parent(node); 13 | if (node && parentElm) { 14 | parentElm.removeChild(node); 15 | } 16 | }); 17 | }; 18 | 19 | /** 20 | * Appends the given children at the end of the given Node. 21 | * @param node The Node to which the children shall be appended. 22 | * @param children The Nodes which shall be appended. 23 | * @returns A function which removes the inserted nodes. 24 | */ 25 | export const appendChildren = (node: NodeElementTarget, children: NodeElementTargetCollection) => 26 | bind( 27 | removeElements, 28 | node && 29 | children && 30 | each(createOrKeepArray(children), (child) => { 31 | if (child) { 32 | node.appendChild(child); 33 | } 34 | }) 35 | ); 36 | -------------------------------------------------------------------------------- /packages/overlayscrollbars/src/support/dom/offset.ts: -------------------------------------------------------------------------------- 1 | import type { HTMLElementTarget } from './types'; 2 | import { getBoundingClientRect } from './dimensions'; 3 | import { wnd } from '../utils/alias'; 4 | 5 | export interface XY { 6 | x: T; 7 | y: T; 8 | } 9 | 10 | const zeroObj: XY = { 11 | x: 0, 12 | y: 0, 13 | }; 14 | 15 | /** 16 | * Returns the offset- left and top coordinates of the passed element relative to the document. If the element is null the top and left values are 0. 17 | * @param elm The element of which the offset- top and left coordinates shall be returned. 18 | */ 19 | export const absoluteCoordinates = (elm: HTMLElementTarget): Readonly => { 20 | const rect = elm && getBoundingClientRect(elm); 21 | return rect 22 | ? { 23 | x: rect.left + wnd.scrollX, 24 | y: rect.top + wnd.scrollY, 25 | } 26 | : zeroObj; 27 | }; 28 | 29 | /** 30 | * Returns the offset- left and top coordinates of the passed element. If the element is null the top and left values are 0. 31 | * @param elm The element of which the offset- top and left coordinates shall be returned. 32 | */ 33 | export const offsetCoordinates = (elm: HTMLElementTarget): Readonly => 34 | elm 35 | ? { 36 | x: elm.offsetLeft, 37 | y: elm.offsetTop, 38 | } 39 | : zeroObj; 40 | -------------------------------------------------------------------------------- /packages/overlayscrollbars/src/support/dom/types.ts: -------------------------------------------------------------------------------- 1 | export type HTMLElementTarget = HTMLElement | false | null | undefined; 2 | export type NodeElementTarget = Node | Element | false | null | undefined; 3 | export type NodeElementTargetCollection = ArrayLike | NodeElementTarget; 4 | -------------------------------------------------------------------------------- /packages/overlayscrollbars/src/support/index.ts: -------------------------------------------------------------------------------- 1 | export * from './cache'; 2 | export * from './compatibility'; 3 | export * from './dom'; 4 | export * from './utils'; 5 | export * from './eventListeners'; 6 | -------------------------------------------------------------------------------- /packages/overlayscrollbars/src/support/utils/alias.ts: -------------------------------------------------------------------------------- 1 | import { isBrowser } from '../compatibility/isBrowser'; 2 | 3 | export const wnd = (isBrowser ? window : {}) as typeof window; 4 | export const mathMax = Math.max; 5 | export const mathMin = Math.min; 6 | export const mathRound = Math.round; 7 | export const mathFloor = Math.floor; 8 | export const mathCeil = Math.ceil; 9 | export const mathAbs = Math.abs; 10 | export const mathSign = Math.sign; 11 | export const cAF = wnd.cancelAnimationFrame; 12 | export const rAF = wnd.requestAnimationFrame; 13 | export const setT = wnd.setTimeout; 14 | export const clearT = wnd.clearTimeout; 15 | -------------------------------------------------------------------------------- /packages/overlayscrollbars/src/support/utils/index.ts: -------------------------------------------------------------------------------- 1 | export * from './animation'; 2 | export * from './array'; 3 | export * from './equal'; 4 | export * from './function'; 5 | export * from './object'; 6 | export * from './types'; 7 | export * from './noop'; 8 | export * from './alias'; 9 | export * from './strings'; 10 | export * from './math'; 11 | -------------------------------------------------------------------------------- /packages/overlayscrollbars/src/support/utils/math.ts: -------------------------------------------------------------------------------- 1 | import { mathMax, mathMin } from './alias'; 2 | 3 | /** 4 | * Caps the passed number between the `min` and `max` bounds. 5 | * @param min The min bound. 6 | * @param max The max bound. 7 | * @param number The number to be capped. 8 | * @returns The capped number between min and max. 9 | */ 10 | export const capNumber = (min: number, max: number, number: number) => 11 | mathMax(min, mathMin(max, number)); 12 | -------------------------------------------------------------------------------- /packages/overlayscrollbars/src/support/utils/noop.ts: -------------------------------------------------------------------------------- 1 | export const noop = () => {}; 2 | -------------------------------------------------------------------------------- /packages/overlayscrollbars/src/support/utils/strings.ts: -------------------------------------------------------------------------------- 1 | export const strPaddingTop = 'paddingTop'; 2 | export const strPaddingRight = 'paddingRight'; 3 | export const strPaddingLeft = 'paddingLeft'; 4 | export const strPaddingBottom = 'paddingBottom'; 5 | export const strMarginLeft = 'marginLeft'; 6 | export const strMarginRight = 'marginRight'; 7 | export const strMarginBottom = 'marginBottom'; 8 | export const strOverflowX = 'overflowX'; 9 | export const strOverflowY = 'overflowY'; 10 | export const strWidth = 'width'; 11 | export const strHeight = 'height'; 12 | export const strVisible = 'visible'; 13 | export const strHidden = 'hidden'; 14 | export const strScroll = 'scroll'; 15 | 16 | export const capitalizeFirstLetter = (str: string | number | false | null | undefined): string => { 17 | const finalStr = String(str || ''); 18 | return finalStr ? finalStr[0].toUpperCase() + finalStr.slice(1) : ''; 19 | }; 20 | -------------------------------------------------------------------------------- /packages/overlayscrollbars/src/trustedTypePolicy.ts: -------------------------------------------------------------------------------- 1 | // at the time of implementation TypeScript doesn't offer any TrustedTypes typescript definitions 2 | // https://github.com/microsoft/TypeScript/issues/30024 3 | let trustedTypePolicy: unknown | undefined; 4 | 5 | export const getTrustedTypePolicy = () => trustedTypePolicy; 6 | export const setTrustedTypePolicy = (newTrustedTypePolicy: unknown | undefined) => { 7 | trustedTypePolicy = newTrustedTypePolicy; 8 | }; 9 | -------------------------------------------------------------------------------- /packages/overlayscrollbars/src/typings.ts: -------------------------------------------------------------------------------- 1 | export type DeepPartial = { 2 | [P in keyof T]?: T[P] extends Record ? DeepPartial : T[P]; 3 | }; 4 | 5 | export type DeepReadonly = { 6 | readonly [P in keyof T]: T[P] extends Record ? DeepReadonly : T[P]; 7 | }; 8 | 9 | // eslint-disable-next-line @typescript-eslint/no-explicit-any 10 | export type PlainObject = { [name: string]: T }; 11 | 12 | export type NonEmptyObject> = 13 | T extends Record ? never : T; 14 | 15 | export type StyleObjectKey = Extract | `--${string}`; 16 | 17 | export type StyleObjectValue = string | number | false | null; 18 | 19 | export type StyleObject = { 20 | [Key in StyleObjectKey]?: StyleObjectValue; 21 | }; 22 | 23 | export type OverflowStyle = 'scroll' | 'hidden' | 'visible'; 24 | -------------------------------------------------------------------------------- /packages/overlayscrollbars/test/dom/instances.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, test, afterEach, expect } from 'vitest'; 2 | import { addInstance, removeInstance, getInstance } from '../../src/instances'; 3 | import { OverlayScrollbars } from '../../src/overlayscrollbars'; 4 | 5 | const testElm = document.body; 6 | const testInstance = OverlayScrollbars(document.body, {}); 7 | 8 | describe('instances', () => { 9 | afterEach(() => { 10 | removeInstance(testElm); 11 | }); 12 | 13 | test('add instance', () => { 14 | addInstance(testElm, testInstance); 15 | 16 | expect(getInstance(testElm)).toBe(testInstance); 17 | }); 18 | 19 | test('remove instance', () => { 20 | addInstance(testElm, testInstance); 21 | removeInstance(testElm); 22 | 23 | expect(getInstance(testElm)).toBe(undefined); 24 | }); 25 | 26 | test('get instance', () => { 27 | addInstance(testElm, testInstance); 28 | 29 | expect(getInstance(testElm)).toBe(testInstance); 30 | }); 31 | }); 32 | -------------------------------------------------------------------------------- /packages/overlayscrollbars/test/dom/nonce.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, test, expect } from 'vitest'; 2 | import { getNonce, setNonce } from '../../src/nonce'; 3 | 4 | describe('nonce', () => { 5 | test('nonce', () => { 6 | expect(getNonce()).toBe(undefined); 7 | 8 | setNonce('123'); 9 | expect(getNonce()).toBe('123'); 10 | 11 | setNonce(undefined); 12 | expect(getNonce()).toBe(undefined); 13 | }); 14 | }); 15 | -------------------------------------------------------------------------------- /packages/overlayscrollbars/test/dom/observers/trinsicObserver.test.ts: -------------------------------------------------------------------------------- 1 | import { vi, describe, test, beforeEach, expect } from 'vitest'; 2 | import { createTrinsicObserver } from '../../../src/observers'; 3 | 4 | describe('createTrinsicObserver', () => { 5 | beforeEach(() => { 6 | document.body.outerHTML = ''; 7 | }); 8 | 9 | test('trinsic observer', () => { 10 | const callback = vi.fn(); 11 | const [construct, update] = createTrinsicObserver(document.body, callback); 12 | 13 | expect(construct).toEqual(expect.any(Function)); 14 | expect(update).toEqual(expect.any(Function)); 15 | 16 | expect(document.body.innerHTML).toBe(''); 17 | 18 | const destroy = construct(); 19 | expect(destroy).toEqual(expect.any(Function)); 20 | 21 | expect(document.body.innerHTML).not.toBe(''); 22 | 23 | destroy(); 24 | 25 | expect(document.body.innerHTML).toBe(''); 26 | }); 27 | }); 28 | -------------------------------------------------------------------------------- /packages/overlayscrollbars/test/dom/support/dom/offset.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, test, expect } from 'vitest'; 2 | import { isNumber, isPlainObject } from '../../../../src/support/utils/types'; 3 | import { absoluteCoordinates, offsetCoordinates } from '../../../../src/support/dom/offset'; 4 | 5 | describe('dom offset', () => { 6 | describe('absoluteCoordinates', () => { 7 | test('DOM element', () => { 8 | const result = absoluteCoordinates(document.body); 9 | expect(isPlainObject(result)).toBe(true); 10 | expect(isNumber(result.x)).toBe(true); 11 | expect(isNumber(result.y)).toBe(true); 12 | }); 13 | 14 | test('null', () => { 15 | const result = absoluteCoordinates(null); 16 | expect(isPlainObject(result)).toBe(true); 17 | expect(result.x).toBe(0); 18 | expect(result.y).toBe(0); 19 | }); 20 | }); 21 | 22 | describe('offsetCoordinates', () => { 23 | test('DOM element', () => { 24 | const result = offsetCoordinates(document.body); 25 | expect(isPlainObject(result)).toBe(true); 26 | expect(isNumber(result.x)).toBe(true); 27 | expect(isNumber(result.y)).toBe(true); 28 | }); 29 | 30 | test('null', () => { 31 | const result = offsetCoordinates(null); 32 | expect(isPlainObject(result)).toBe(true); 33 | expect(result.x).toBe(0); 34 | expect(result.y).toBe(0); 35 | }); 36 | }); 37 | }); 38 | -------------------------------------------------------------------------------- /packages/overlayscrollbars/test/dom/support/utils/math.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, test, expect } from 'vitest'; 2 | import { capNumber } from '../../../../src/support/utils/math'; 3 | 4 | describe('math utilities', () => { 5 | test('capNumber', () => { 6 | expect(capNumber(0, 1, 100)).toBe(1); 7 | expect(capNumber(0, 1, -100)).toBe(0); 8 | expect(capNumber(0, 1, 0.5)).toBe(0.5); 9 | expect(capNumber(0, 1, 0.25)).toBe(0.25); 10 | expect(capNumber(0, 1, 0.75)).toBe(0.75); 11 | expect(capNumber(0, 1, 0)).toBe(0); 12 | expect(capNumber(0, 1, 1)).toBe(1); 13 | }); 14 | }); 15 | -------------------------------------------------------------------------------- /packages/overlayscrollbars/test/dom/support/utils/strings.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, test, expect } from 'vitest'; 2 | import { capitalizeFirstLetter } from '../../../../src/support/utils/strings'; 3 | 4 | describe('strings', () => { 5 | test('capitalizeFirstLetter', () => { 6 | expect(capitalizeFirstLetter('test')).toBe('Test'); 7 | expect(capitalizeFirstLetter(null)).toBe(''); 8 | }); 9 | }); 10 | -------------------------------------------------------------------------------- /packages/overlayscrollbars/test/dom/trustedTypePolicy.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, test, expect } from 'vitest'; 2 | import { getTrustedTypePolicy, setTrustedTypePolicy } from '../../src/trustedTypePolicy'; 3 | 4 | describe('trustedTypePolicy', () => { 5 | test('trustedTypePolicy', () => { 6 | expect(getTrustedTypePolicy()).toBe(undefined); 7 | 8 | setTrustedTypePolicy('123'); 9 | expect(getTrustedTypePolicy()).toBe('123'); 10 | 11 | setTrustedTypePolicy(undefined); 12 | expect(getTrustedTypePolicy()).toBe(undefined); 13 | }); 14 | }); 15 | -------------------------------------------------------------------------------- /packages/overlayscrollbars/test/node/server.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, test, expect } from 'vitest'; 2 | 3 | describe('usage on server', () => { 4 | test('import', async () => { 5 | await expect( 6 | (async () => { 7 | const module = await import('../../src/index'); 8 | return module; 9 | })() 10 | ).resolves.toBeTruthy(); 11 | }); 12 | 13 | test('static functions', async () => { 14 | await expect( 15 | (async () => { 16 | const { OverlayScrollbars } = await import('../../src/index'); 17 | 18 | expect(() => { 19 | OverlayScrollbars.valid(false); 20 | }).not.toThrow(); 21 | expect(() => { 22 | OverlayScrollbars.plugin({}); 23 | }).not.toThrow(); 24 | })() 25 | ).resolves.not.toThrow(); 26 | }); 27 | }); 28 | -------------------------------------------------------------------------------- /packages/overlayscrollbars/test/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "type": "module", 4 | "sideEffects": true 5 | } 6 | -------------------------------------------------------------------------------- /packages/overlayscrollbars/test/playwright/appear/handleEnvironment.ts: -------------------------------------------------------------------------------- 1 | { 2 | const { body } = document; 3 | const url = new URL(window.location.toString()); 4 | const params = url.searchParams; 5 | 6 | /** 7 | * autoHideSuspend: autoHideSuspend = true 8 | */ 9 | ['autoHideSuspend'].forEach((param) => { 10 | const paramValue = Boolean(params.get(param)); 11 | 12 | if (paramValue) { 13 | body.classList.add(param); 14 | } else { 15 | document.getElementById(param)?.addEventListener('click', () => { 16 | params.set(param, 'true'); 17 | window.location.assign(url.toString()); 18 | }); 19 | } 20 | }); 21 | } 22 | -------------------------------------------------------------------------------- /packages/overlayscrollbars/test/playwright/appear/index.html: -------------------------------------------------------------------------------- 1 |
2 | 3 | 4 | 5 | 6 |
7 | Appears: 8 | TargetA=0 9 | TargetB=0 10 | TargetC=0 11 | TargetD=0 12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 | -------------------------------------------------------------------------------- /packages/overlayscrollbars/test/playwright/appear/index.scss: -------------------------------------------------------------------------------- 1 | * { 2 | scroll-behavior: smooth; 3 | } 4 | body { 5 | display: flex; 6 | flex-direction: column; 7 | } 8 | #controls { 9 | flex: none; 10 | } 11 | #stage { 12 | flex: auto; 13 | position: relative; 14 | 15 | & > div { 16 | position: absolute; 17 | top: 0; 18 | right: 0; 19 | bottom: 0; 20 | left: 0; 21 | background: lightgoldenrodyellow; 22 | } 23 | } 24 | 25 | .row { 26 | width: 100%; 27 | height: 50%; 28 | display: flex; 29 | align-items: center; 30 | justify-content: center; 31 | } 32 | 33 | .target { 34 | width: 50%; 35 | height: 100%; 36 | display: none; 37 | } 38 | .content { 39 | width: 300%; 40 | height: 300%; 41 | } 42 | 43 | #targetA { 44 | background: rgba(255, 0, 0, 0.25); 45 | &.appear { 46 | display: flex; 47 | } 48 | } 49 | #targetB { 50 | background: rgba(0, 0, 255, 0.25); 51 | &.appear { 52 | display: block; 53 | } 54 | } 55 | #targetC { 56 | background: rgba(0, 255, 0, 0.25); 57 | &.appear { 58 | display: flex; 59 | } 60 | } 61 | #targetD { 62 | background: rgba(255, 0, 255, 0.25); 63 | &.appear { 64 | display: block; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /packages/overlayscrollbars/test/playwright/appear/index.test.ts: -------------------------------------------------------------------------------- 1 | import { playwrightRollup, expectSuccess } from '@~local/playwright-tooling'; 2 | import { test } from '@playwright/test'; 3 | 4 | playwrightRollup(); 5 | 6 | test.describe('appear', () => { 7 | test.beforeEach(async ({ page }) => { 8 | await page.mouse.move(0, 0); 9 | }); 10 | 11 | test('default', async ({ page }) => { 12 | await expectSuccess(page); 13 | }); 14 | 15 | test('with autoHideSuspend', async ({ page }) => { 16 | await page.click('#autoHideSuspend'); 17 | await expectSuccess(page); 18 | }); 19 | }); 20 | -------------------------------------------------------------------------------- /packages/overlayscrollbars/test/playwright/environment/index.browser.ts: -------------------------------------------------------------------------------- 1 | import '~/index.scss'; 2 | import { createDOM, appendChildren } from '~/support'; 3 | import { getEnvironment } from '~/environment'; 4 | 5 | const envInstance = getEnvironment(); 6 | appendChildren(document.body, createDOM(`
${JSON.stringify(envInstance)}
`)[0]); 7 | 8 | export { envInstance }; 9 | -------------------------------------------------------------------------------- /packages/overlayscrollbars/test/playwright/environment/index.html: -------------------------------------------------------------------------------- 1 | hi 2 | -------------------------------------------------------------------------------- /packages/overlayscrollbars/test/playwright/environment/index.test.ts: -------------------------------------------------------------------------------- 1 | /* 2 | import { playwrightRollup } from '@~local/playwright-tooling'; 3 | import { test } from '@playwright/test'; 4 | import { InternalEnvironment } from '~/environment'; 5 | 6 | playwrightRollup(); 7 | 8 | test.describe('Environment', () => { 9 | test('page should be titled "Environment"', async ({ page }) => { 10 | // @ts-ignore 11 | const a: InternalEnvironment = await page.evaluate(() => window.environment.envInstance); 12 | console.log(a); 13 | await expect(page.title()).resolves.toMatch('environment'); 14 | }); 15 | }); 16 | */ 17 | -------------------------------------------------------------------------------- /packages/overlayscrollbars/test/playwright/observers/domObserver/index.test.ts: -------------------------------------------------------------------------------- 1 | import { playwrightRollup, expectSuccess } from '@~local/playwright-tooling'; 2 | import { test } from '@playwright/test'; 3 | 4 | playwrightRollup(); 5 | 6 | test.describe('DOMObserver', () => { 7 | test('test', async ({ page }) => { 8 | await expectSuccess(page); 9 | }); 10 | }); 11 | -------------------------------------------------------------------------------- /packages/overlayscrollbars/test/playwright/observers/sizeObserver/handleEnvironment.ts: -------------------------------------------------------------------------------- 1 | { 2 | const { body } = document; 3 | const url = new URL(window.location.toString()); 4 | const params = url.searchParams; 5 | 6 | /** 7 | * roPolyfill: no ResizeObserver supported, use polyfill 8 | * roNoBox: ResizeObserver supported but no options.box support in the `observe` function 9 | */ 10 | ['roPolyfill', 'roNoBox'].forEach((param) => { 11 | const paramValue = Boolean(params.get(param)); 12 | 13 | if (paramValue) { 14 | body.classList.add(param); 15 | 16 | switch (param) { 17 | case 'roPolyfill': { 18 | // @ts-ignore 19 | window.ResizeObserver = undefined; 20 | break; 21 | } 22 | case 'roNoBox': { 23 | const originalProtoType = window.ResizeObserver.prototype; 24 | const originalObserve = originalProtoType.observe; 25 | 26 | originalProtoType.observe = function (target) { 27 | originalObserve.apply(this, [target]); 28 | }; 29 | break; 30 | } 31 | } 32 | } else { 33 | document.getElementById(param)?.addEventListener('click', () => { 34 | params.set(param, 'true'); 35 | window.location.assign(url.toString()); 36 | }); 37 | } 38 | }); 39 | } 40 | -------------------------------------------------------------------------------- /packages/overlayscrollbars/test/playwright/observers/sizeObserver/index.test.ts: -------------------------------------------------------------------------------- 1 | import { playwrightRollup, expectSuccess } from '@~local/playwright-tooling'; 2 | import { test } from '@playwright/test'; 3 | 4 | playwrightRollup(); 5 | 6 | test.describe('SizeObserver', () => { 7 | test('with ResizeOserver', async ({ page }) => { 8 | await expectSuccess(page); 9 | }); 10 | 11 | test('with ResizeOserver without options.box', async ({ page }) => { 12 | await page.click('#roNoBox'); 13 | 14 | await expectSuccess(page); 15 | }); 16 | 17 | test('with ResizeOserver polyfill', async ({ page }) => { 18 | await page.click('#roPolyfill'); 19 | 20 | await expectSuccess(page); 21 | }); 22 | }); 23 | -------------------------------------------------------------------------------- /packages/overlayscrollbars/test/playwright/observers/trinsicObserver/handleEnvironment.ts: -------------------------------------------------------------------------------- 1 | { 2 | const url = new URL(window.location.toString()); 3 | const params = url.searchParams; 4 | const useIntersectionObserverPolyfill = Boolean(params.get('ioPolyfill')); 5 | const useResizeObserverPolyfill = Boolean(params.get('roPolyfill')); 6 | 7 | if (useIntersectionObserverPolyfill) { 8 | // @ts-ignore 9 | window.IntersectionObserver = undefined; 10 | } else { 11 | document.getElementById('ioPolyfill')?.addEventListener('click', () => { 12 | params.set('ioPolyfill', 'true'); 13 | window.location.assign(url.toString()); 14 | }); 15 | } 16 | 17 | if (useResizeObserverPolyfill) { 18 | // @ts-ignore 19 | window.ResizeObserver = undefined; 20 | } else { 21 | document.getElementById('roPolyfill')?.addEventListener('click', () => { 22 | params.set('roPolyfill', 'true'); 23 | window.location.assign(url.toString()); 24 | }); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /packages/overlayscrollbars/test/playwright/observers/trinsicObserver/index.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 | 5 | 9 | 10 | 15 | 16 | 21 | 22 | 23 | Detected changes: 0 24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 | -------------------------------------------------------------------------------- /packages/overlayscrollbars/test/playwright/observers/trinsicObserver/index.scss: -------------------------------------------------------------------------------- 1 | body { 2 | display: flex; 3 | flex-direction: column; 4 | } 5 | #controls { 6 | flex: none; 7 | } 8 | #stage { 9 | flex: auto; 10 | position: relative; 11 | 12 | & > div { 13 | position: absolute; 14 | top: 0; 15 | right: 0; 16 | bottom: 0; 17 | left: 0; 18 | background: lightgoldenrodyellow; 19 | } 20 | } 21 | 22 | #canvas > div { 23 | position: absolute; 24 | top: 0; 25 | right: 0; 26 | bottom: 0; 27 | left: 0; 28 | } 29 | 30 | #env { 31 | background: rgba(0, 0, 0, 0.3); 32 | } 33 | 34 | #target { 35 | background: rgba(0, 0, 0, 0.3); 36 | overflow: hidden; 37 | position: relative; 38 | // prevent container from reaching 0x0 dimensions for testing purposes 39 | min-width: 50px; 40 | min-height: 50px; 41 | } 42 | 43 | #check { 44 | height: 100%; 45 | } 46 | 47 | .envHeightAuto, 48 | .targetHeightAuto { 49 | height: auto; 50 | } 51 | 52 | .envHeight200, 53 | .targetHeight200 { 54 | height: 200px; 55 | } 56 | 57 | .envHeightHundred, 58 | .targetHeightHundred { 59 | height: 100%; 60 | } 61 | 62 | .displayNone { 63 | display: none; 64 | } 65 | .displayBlock { 66 | display: block; 67 | } 68 | -------------------------------------------------------------------------------- /packages/overlayscrollbars/test/playwright/observers/trinsicObserver/index.test.ts: -------------------------------------------------------------------------------- 1 | import { playwrightRollup, expectSuccess } from '@~local/playwright-tooling'; 2 | import { test } from '@playwright/test'; 3 | 4 | playwrightRollup(); 5 | 6 | test.describe('TrinsicObserver', () => { 7 | test('with IntersectionObserver', async ({ page }) => { 8 | await expectSuccess(page); 9 | }); 10 | 11 | /* 12 | // there is no scenario where IntersectionObserver not supported and ResizeObserver is: 13 | // https://caniuse.com/intersectionobserver 14 | // https://caniuse.com/?search=resizeobserver 15 | test('with ResizeObserver', async ({ page }) => { 16 | await page.click('#ioPolyfill'); 17 | 18 | await expectSuccess(page); 19 | }); 20 | */ 21 | 22 | test('with ResizeObserver polyfill', async ({ page }) => { 23 | await page.click('#ioPolyfill'); 24 | await page.click('#roPolyfill'); 25 | 26 | await expectSuccess(page); 27 | }); 28 | }); 29 | -------------------------------------------------------------------------------- /packages/overlayscrollbars/test/playwright/performance/fps/index.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 | -------------------------------------------------------------------------------- /packages/overlayscrollbars/test/playwright/performance/fps/index.scss: -------------------------------------------------------------------------------- 1 | body { 2 | display: flex; 3 | flex-direction: column; 4 | } 5 | #controls { 6 | flex: none; 7 | } 8 | #stage { 9 | flex: auto; 10 | position: relative; 11 | 12 | & > div { 13 | position: absolute; 14 | top: 0; 15 | right: 0; 16 | bottom: 0; 17 | left: 0; 18 | background: lightgoldenrodyellow; 19 | } 20 | } 21 | 22 | .row { 23 | width: 100%; 24 | height: 50%; 25 | display: flex; 26 | align-items: center; 27 | justify-content: center; 28 | } 29 | 30 | #content { 31 | width: 300%; 32 | height: 300%; 33 | border: 2px solid blue; 34 | } 35 | 36 | #target { 37 | background: rgba(255, 0, 0, 0.25); 38 | width: 100%; 39 | height: 100%; 40 | overflow: auto; 41 | } 42 | 43 | .resizer { 44 | position: relative; 45 | } 46 | 47 | .resizeBtn { 48 | position: absolute; 49 | bottom: 0; 50 | right: 0; 51 | height: 20px; 52 | width: 20px; 53 | background: red; 54 | opacity: 0.3; 55 | } 56 | -------------------------------------------------------------------------------- /packages/overlayscrollbars/test/playwright/performance/fps/index.test.ts: -------------------------------------------------------------------------------- 1 | import { playwrightRollup, expectSuccess } from '@~local/playwright-tooling'; 2 | import { test } from '@playwright/test'; 3 | 4 | playwrightRollup(); 5 | 6 | test.describe('performance.fps', () => { 7 | test('default', async ({ page }) => { 8 | await expectSuccess(page); 9 | }); 10 | }); 11 | -------------------------------------------------------------------------------- /packages/overlayscrollbars/test/playwright/performance/timing/handleEnvironment.ts: -------------------------------------------------------------------------------- 1 | { 2 | const { body } = document; 3 | const url = new URL(window.location.toString()); 4 | const params = url.searchParams; 5 | 6 | /** 7 | * ndsd: non default scroll direction = true 8 | */ 9 | ['ndsd'].forEach((param) => { 10 | const paramValue = Boolean(params.get(param)); 11 | 12 | if (paramValue) { 13 | body.classList.add(param); 14 | } else { 15 | document.getElementById(param)?.addEventListener('click', () => { 16 | params.set(param, 'true'); 17 | window.location.assign(url.toString()); 18 | }); 19 | } 20 | }); 21 | } 22 | -------------------------------------------------------------------------------- /packages/overlayscrollbars/test/playwright/performance/timing/index.html: -------------------------------------------------------------------------------- 1 |
2 | 3 | 4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 | -------------------------------------------------------------------------------- /packages/overlayscrollbars/test/playwright/performance/timing/index.scss: -------------------------------------------------------------------------------- 1 | body { 2 | display: flex; 3 | flex-direction: column; 4 | } 5 | #controls { 6 | flex: none; 7 | } 8 | #stage { 9 | flex: auto; 10 | position: relative; 11 | 12 | & > div { 13 | position: absolute; 14 | top: 0; 15 | right: 0; 16 | bottom: 0; 17 | left: 0; 18 | background: lightgoldenrodyellow; 19 | } 20 | } 21 | 22 | .row { 23 | width: 100%; 24 | height: 50%; 25 | display: flex; 26 | align-items: center; 27 | justify-content: center; 28 | } 29 | 30 | #content { 31 | width: 300%; 32 | height: 300%; 33 | border: 2px solid blue; 34 | } 35 | 36 | #target { 37 | background: rgba(255, 0, 0, 0.25); 38 | width: 100%; 39 | height: 100%; 40 | overflow: auto; 41 | } 42 | 43 | .resizer { 44 | position: relative; 45 | } 46 | 47 | .resizeBtn { 48 | position: absolute; 49 | bottom: 0; 50 | right: 0; 51 | height: 20px; 52 | width: 20px; 53 | background: red; 54 | opacity: 0.3; 55 | } 56 | 57 | body.ndsd { 58 | direction: rtl; 59 | } 60 | -------------------------------------------------------------------------------- /packages/overlayscrollbars/test/playwright/performance/timing/index.test.ts: -------------------------------------------------------------------------------- 1 | import { playwrightRollup, expectSuccess } from '@~local/playwright-tooling'; 2 | import { test } from '@playwright/test'; 3 | 4 | playwrightRollup(); 5 | 6 | test.describe('performance.timing', () => { 7 | test('default', async ({ page }) => { 8 | await expectSuccess(page); 9 | }); 10 | 11 | test('non default scroll direction', async ({ page }) => { 12 | await page.click('#ndsd'); 13 | await expectSuccess(page); 14 | }); 15 | }); 16 | -------------------------------------------------------------------------------- /packages/overlayscrollbars/test/playwright/scrollSnap/index.test.ts: -------------------------------------------------------------------------------- 1 | import { playwrightRollup, expectSuccess } from '@~local/playwright-tooling'; 2 | import { test } from '@playwright/test'; 3 | 4 | playwrightRollup(); 5 | 6 | test.describe('scrollSnap', () => { 7 | test('default', async ({ page }) => { 8 | await expectSuccess(page); 9 | }); 10 | }); 11 | -------------------------------------------------------------------------------- /packages/overlayscrollbars/test/playwright/setups/scrollbarsSetup/scrollbars/handleEnvironment.ts: -------------------------------------------------------------------------------- 1 | { 2 | const { body } = document; 3 | const url = new URL(window.location.toString()); 4 | const params = url.searchParams; 5 | 6 | /** 7 | * scrollT: disable scrollTimeline 8 | */ 9 | ['scrollT'].forEach((param) => { 10 | const paramValue = Boolean(params.get(param)); 11 | 12 | if (paramValue) { 13 | body.classList.add(param); 14 | } else { 15 | document.getElementById(param)?.addEventListener('click', () => { 16 | params.set(param, 'true'); 17 | window.location.assign(url.toString()); 18 | }); 19 | } 20 | }); 21 | 22 | const withoutScrollTimeline = document.body.classList.contains('scrollT'); 23 | if (withoutScrollTimeline) { 24 | // @ts-ignore 25 | window.ScrollTimeline = undefined; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /packages/overlayscrollbars/test/playwright/setups/scrollbarsSetup/scrollbars/index.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 | 5 | 6 | 7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 | -------------------------------------------------------------------------------- /packages/overlayscrollbars/test/playwright/setups/structureSetup/body/handleEnvironment.ts: -------------------------------------------------------------------------------- 1 | import { addClass } from '~/support'; 2 | 3 | { 4 | const { body } = document; 5 | const url = new URL(window.location.toString()); 6 | const params = url.searchParams; 7 | 8 | /** 9 | * nsh: native scrollbar hiding 10 | */ 11 | ['nsh'].forEach((param) => { 12 | const paramValue = Boolean(params.get(param)); 13 | 14 | if (paramValue) { 15 | addClass(body, param); 16 | } else { 17 | document.getElementById(param)?.addEventListener('click', () => { 18 | params.set(param, 'true'); 19 | window.location.assign(url.toString()); 20 | }); 21 | } 22 | }); 23 | 24 | body.setAttribute('data-overlayscrollbars-initialize', ''); 25 | body.parentElement?.setAttribute('data-overlayscrollbars-initialize', ''); 26 | } 27 | -------------------------------------------------------------------------------- /packages/overlayscrollbars/test/playwright/setups/structureSetup/body/index.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 | 5 |
6 |
7 | content 8 |
9 |
10 | -------------------------------------------------------------------------------- /packages/overlayscrollbars/test/playwright/setups/structureSetup/body/index.scss: -------------------------------------------------------------------------------- 1 | html, 2 | body { 3 | margin: unset; 4 | padding: unset; 5 | width: unset; 6 | height: unset; 7 | } 8 | 9 | html.padding { 10 | padding: 20px 5px 8px 13px; 11 | 12 | body { 13 | padding: 20px 5px 8px 13px; 14 | } 15 | } 16 | 17 | html.margin { 18 | margin: 3px 20px 12px 7px; 19 | 20 | body { 21 | margin: 3px 20px 12px 7px; 22 | } 23 | } 24 | 25 | #controls { 26 | position: fixed; 27 | flex: none; 28 | z-index: 1; 29 | } 30 | 31 | #content { 32 | background: rgba(255, 0, 0, 0.4); 33 | height: 150vh; 34 | width: 150vw; 35 | position: relative; 36 | } 37 | 38 | #content::before { 39 | content: ''; 40 | display: block; 41 | width: 100%; 42 | height: 100%; 43 | position: absolute; 44 | bottom: 0; 45 | right: 0; 46 | border: 2px solid blue; 47 | } 48 | 49 | #scrollTarget { 50 | background: green; 51 | width: 1px; 52 | height: 1px; 53 | position: absolute; 54 | bottom: 0; 55 | right: 0; 56 | } 57 | 58 | body.nsh { 59 | .os-environment-scrollbar-hidden { 60 | scrollbar-width: auto !important; 61 | } 62 | .os-environment-scrollbar-hidden::-webkit-scrollbar, 63 | .os-environment-scrollbar-hidden::-webkit-scrollbar-corner { 64 | display: block !important; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /packages/overlayscrollbars/test/playwright/setups/structureSetup/body/index.test.ts: -------------------------------------------------------------------------------- 1 | import { playwrightRollup, expectSuccess } from '@~local/playwright-tooling'; 2 | import { test } from '@playwright/test'; 3 | 4 | playwrightRollup(); 5 | 6 | test.describe('StructureSetup.body', () => { 7 | test('with native scrollbar styling', async ({ page }) => { 8 | await expectSuccess(page); 9 | }); 10 | 11 | test('without native scrollbar styling', async ({ page }) => { 12 | await page.click('#nsh'); 13 | await expectSuccess(page); 14 | }); 15 | }); 16 | -------------------------------------------------------------------------------- /packages/overlayscrollbars/test/playwright/setups/structureSetup/focus/handleEnvironment.ts: -------------------------------------------------------------------------------- 1 | import { addClass } from '~/support'; 2 | 3 | { 4 | const { body } = document; 5 | const url = new URL(window.location.toString()); 6 | const params = url.searchParams; 7 | 8 | /** 9 | * nsh: native scrollbar hiding 10 | * vpt: viewport is target 11 | */ 12 | ['nsh', 'vpt'].forEach((param) => { 13 | const paramValue = Boolean(params.get(param)); 14 | 15 | if (paramValue) { 16 | addClass(body, param); 17 | } else { 18 | document.getElementById(param)?.addEventListener('click', () => { 19 | params.set(param, 'true'); 20 | window.location.assign(url.toString()); 21 | }); 22 | } 23 | }); 24 | } 25 | -------------------------------------------------------------------------------- /packages/overlayscrollbars/test/playwright/setups/structureSetup/focus/index.html: -------------------------------------------------------------------------------- 1 |
2 | 3 | 4 |
5 | 6 |
7 |
8 |
9 |
10 |
11 |
12 | 13 |
14 |
15 |
16 |
17 |
18 | -------------------------------------------------------------------------------- /packages/overlayscrollbars/test/playwright/setups/structureSetup/focus/index.scss: -------------------------------------------------------------------------------- 1 | * { 2 | scroll-behavior: smooth; 3 | } 4 | body { 5 | display: flex; 6 | flex-direction: column; 7 | } 8 | #controls { 9 | flex: none; 10 | } 11 | #stage { 12 | flex: auto; 13 | position: relative; 14 | 15 | & > div { 16 | position: absolute; 17 | top: 0; 18 | right: 0; 19 | bottom: 0; 20 | left: 0; 21 | background: lightgoldenrodyellow; 22 | } 23 | } 24 | 25 | .element { 26 | width: 100%; 27 | height: 100%; 28 | display: flex; 29 | align-items: center; 30 | justify-content: center; 31 | } 32 | 33 | body.nsh { 34 | .os-environment-scrollbar-hidden { 35 | scrollbar-width: auto !important; 36 | } 37 | .os-environment-scrollbar-hidden::-webkit-scrollbar, 38 | .os-environment-scrollbar-hidden::-webkit-scrollbar-corner { 39 | display: block !important; 40 | } 41 | } 42 | 43 | .os-scrollbar { 44 | opacity: 1 !important; 45 | visibility: visible !important; 46 | background: red !important; 47 | } 48 | -------------------------------------------------------------------------------- /packages/overlayscrollbars/test/playwright/setups/structureSetup/focus/index.test.ts: -------------------------------------------------------------------------------- 1 | import { playwrightRollup, expectSuccess } from '@~local/playwright-tooling'; 2 | import { test } from '@playwright/test'; 3 | 4 | playwrightRollup(); 5 | 6 | test.describe('StructureSetup.focus', () => { 7 | test.describe('with native scrollbar styling', () => { 8 | test('default', async ({ page }) => { 9 | await expectSuccess(page); 10 | }); 11 | 12 | test('viewport is target', async ({ page }) => { 13 | await page.click('#vpt'); 14 | await expectSuccess(page); 15 | }); 16 | }); 17 | 18 | test('without native scrollbar styling', async ({ page }) => { 19 | await page.click('#nsh'); 20 | await expectSuccess(page); 21 | }); 22 | }); 23 | -------------------------------------------------------------------------------- /packages/overlayscrollbars/test/playwright/setups/structureSetup/initScroll/handleEnvironment.ts: -------------------------------------------------------------------------------- 1 | import { addClass } from '~/support'; 2 | 3 | { 4 | const { body } = document; 5 | const url = new URL(window.location.toString()); 6 | const params = url.searchParams; 7 | 8 | /** 9 | * vpt: viewport is target 10 | * vps: viewport is element with valid scroll 11 | * vp: viewport is element without valid scroll 12 | */ 13 | ['vpt', 'vps', 'vp'].forEach((param) => { 14 | const paramValue = Boolean(params.get(param)); 15 | 16 | if (paramValue) { 17 | addClass(body, param); 18 | } else { 19 | document.getElementById(param)?.addEventListener('click', () => { 20 | params.set(param, 'true'); 21 | window.location.assign(url.toString()); 22 | }); 23 | } 24 | }); 25 | } 26 | -------------------------------------------------------------------------------- /packages/overlayscrollbars/test/playwright/setups/structureSetup/initScroll/index.html: -------------------------------------------------------------------------------- 1 |
2 | 3 | 4 | 5 |
6 | 7 |
8 |
9 |
10 |
11 |
12 |
13 |

hi

14 |
15 |
16 |
17 |
18 |
19 | -------------------------------------------------------------------------------- /packages/overlayscrollbars/test/playwright/setups/structureSetup/initScroll/index.scss: -------------------------------------------------------------------------------- 1 | * { 2 | scroll-behavior: smooth; 3 | } 4 | body { 5 | display: flex; 6 | flex-direction: column; 7 | } 8 | #controls { 9 | flex: none; 10 | } 11 | #stage { 12 | flex: auto; 13 | position: relative; 14 | 15 | & > div { 16 | position: absolute; 17 | top: 0; 18 | right: 0; 19 | bottom: 0; 20 | left: 0; 21 | background: lightgoldenrodyellow; 22 | } 23 | } 24 | 25 | #target, 26 | body.vps #viewport { 27 | overflow: auto; 28 | position: absolute; 29 | top: 0; 30 | right: 0; 31 | bottom: 0; 32 | left: 0; 33 | } 34 | 35 | #element { 36 | margin-top: 200vh; 37 | margin-left: 200vw; 38 | } 39 | 40 | #hi { 41 | display: inline-block; 42 | margin: 0; 43 | padding: 0; 44 | } 45 | -------------------------------------------------------------------------------- /packages/overlayscrollbars/test/playwright/setups/structureSetup/initScroll/index.test.ts: -------------------------------------------------------------------------------- 1 | import { playwrightRollup, expectSuccess } from '@~local/playwright-tooling'; 2 | import { test } from '@playwright/test'; 3 | 4 | playwrightRollup({ 5 | adaptUrl: (originalUrl) => { 6 | const url = new URL(originalUrl); 7 | url.hash = '#hi'; 8 | return url.href; 9 | }, 10 | }); 11 | 12 | test.describe('StructureSetup.initScroll', () => { 13 | test('default', async ({ page }) => { 14 | await expectSuccess(page); 15 | }); 16 | 17 | test('viewport with scrollable overflow', async ({ page }) => { 18 | await page.click('#vps'); 19 | await expectSuccess(page); 20 | }); 21 | 22 | test('viewport without scrollable overflow', async ({ page }) => { 23 | await page.click('#vp'); 24 | await expectSuccess(page); 25 | }); 26 | 27 | test('viewport is target', async ({ page }) => { 28 | await page.click('#vpt'); 29 | await expectSuccess(page); 30 | }); 31 | }); 32 | -------------------------------------------------------------------------------- /packages/overlayscrollbars/test/playwright/setups/structureSetup/nesting/index.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
UpdatesC:
11 |
12 |
UpdatesB:
13 |
14 |
UpdatesA:
15 |
16 |
UpdatesRoot:
17 |
18 |
19 |
20 | -------------------------------------------------------------------------------- /packages/overlayscrollbars/test/playwright/setups/structureSetup/nesting/index.scss: -------------------------------------------------------------------------------- 1 | * { 2 | scroll-behavior: smooth; 3 | } 4 | body { 5 | display: flex; 6 | flex-direction: column; 7 | overflow: scroll; 8 | } 9 | #controls { 10 | flex: none; 11 | } 12 | #stage { 13 | flex: auto; 14 | position: relative; 15 | 16 | & > div { 17 | position: absolute; 18 | top: 0; 19 | right: 0; 20 | bottom: 0; 21 | left: 0; 22 | background: lightgoldenrodyellow; 23 | } 24 | } 25 | 26 | .container { 27 | border: 1px solid red; 28 | width: 75%; 29 | height: 60%; 30 | padding: 10px; 31 | margin: 10px; 32 | } 33 | 34 | .resize { 35 | overflow: hidden; 36 | background: lime; 37 | border: 1px solid green; 38 | padding: 10px; 39 | } 40 | 41 | .resizer { 42 | position: relative; 43 | } 44 | 45 | .resizeBetween { 46 | background: tomato; 47 | position: absolute; 48 | bottom: 0; 49 | left: 0; 50 | } 51 | 52 | .resizeBtn { 53 | position: absolute; 54 | bottom: 0; 55 | right: 0; 56 | height: 20px; 57 | width: 20px; 58 | background: blue; 59 | opacity: 0.3; 60 | } 61 | 62 | #targetRoot { 63 | height: 80%; 64 | } 65 | 66 | #targetA { 67 | box-sizing: border-box; 68 | } 69 | 70 | #targetC { 71 | height: auto; 72 | } 73 | 74 | .flex { 75 | display: flex; 76 | 77 | & > .resize { 78 | width: 80px; 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /packages/overlayscrollbars/test/playwright/setups/structureSetup/nesting/index.test.ts: -------------------------------------------------------------------------------- 1 | import { playwrightRollup, expectSuccess } from '@~local/playwright-tooling'; 2 | import { test } from '@playwright/test'; 3 | 4 | playwrightRollup(); 5 | 6 | test.describe('StructureSetup.nesting', () => { 7 | test('nesting updates', async ({ page }) => { 8 | await expectSuccess(page); 9 | }); 10 | }); 11 | -------------------------------------------------------------------------------- /packages/overlayscrollbars/test/playwright/setups/structureSetup/update/handleEnvironment.ts: -------------------------------------------------------------------------------- 1 | import { addClass } from '~/support'; 2 | 3 | { 4 | const { body } = document; 5 | const url = new URL(window.location.toString()); 6 | const params = url.searchParams; 7 | 8 | /** 9 | * fast: faster but not so accurate run 10 | * nsh: native scrollbar hiding 11 | * po: partially overlaid 12 | * fo: fully overlaid 13 | * vpt: viewport is target 14 | * pa: padding absolute 15 | */ 16 | ['fast', 'nsh', 'po', 'fo', 'vpt', 'pa'].forEach((param) => { 17 | const paramValue = Boolean(params.get(param)); 18 | 19 | if (paramValue) { 20 | addClass(body, param); 21 | } else { 22 | document.getElementById(param)?.addEventListener('click', () => { 23 | params.set(param, 'true'); 24 | window.location.assign(url.toString()); 25 | }); 26 | } 27 | }); 28 | } 29 | -------------------------------------------------------------------------------- /packages/overlayscrollbars/test/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "baseUrl": "../", 5 | "paths": { 6 | "~/*": ["./src/*"] 7 | }, 8 | "types": ["node"] 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /packages/overlayscrollbars/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@~local/tsconfig", 3 | "compilerOptions": { 4 | "types": ["node"], 5 | }, 6 | "exclude": ["dist"] 7 | } 8 | -------------------------------------------------------------------------------- /packages/overlayscrollbars/tsconfig.types.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "rootDir": "./src/", 5 | "outDir": "./types", 6 | "declaration": true 7 | }, 8 | "include": ["src/**/*"] 9 | } 10 | -------------------------------------------------------------------------------- /packages/overlayscrollbars/vitest.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vitest/config'; 2 | import { vitestConfig } from '@~local/config/vitest'; 3 | 4 | export default defineConfig({ 5 | test: { 6 | ...vitestConfig.test, 7 | }, 8 | }); 9 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@~local/tsconfig", 3 | "exclude": ["**/dist/**/*", "**/build/**/*"] 4 | } 5 | -------------------------------------------------------------------------------- /website/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # next.js 12 | /.next/ 13 | /out/ 14 | /dist 15 | 16 | # production 17 | /build 18 | /dist 19 | 20 | # misc 21 | .DS_Store 22 | *.pem 23 | 24 | # debug 25 | npm-debug.log* 26 | yarn-debug.log* 27 | yarn-error.log* 28 | 29 | # local env files 30 | .env*.local 31 | 32 | # vercel 33 | .vercel 34 | 35 | # typescript 36 | *.tsbuildinfo 37 | next-env.d.ts 38 | -------------------------------------------------------------------------------- /website/app/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KingSora/OverlayScrollbars/9cb3e2249f4be85e1e27753a85d20c00fc68cbda/website/app/favicon.ico -------------------------------------------------------------------------------- /website/app/styles.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: 'Inter'; 3 | font-style: normal; 4 | font-weight: 100 1000; 5 | font-display: swap; 6 | src: url('/OverlayScrollbars/font/inter/inter-variable-slnt-wght.woff2') 7 | format('woff2 supports variations'), 8 | url('/OverlayScrollbars/font/inter/inter-variable-slnt-wght.woff2') format('woff2-variations'); 9 | } 10 | 11 | @tailwind base; 12 | @tailwind components; 13 | @tailwind utilities; 14 | -------------------------------------------------------------------------------- /website/components/Icon.tsx: -------------------------------------------------------------------------------- 1 | import { forwardRef } from 'react'; 2 | import cn from 'classnames'; 3 | import type { ComponentPropsWithoutRef } from 'react'; 4 | 5 | export interface IconProps extends ComponentPropsWithoutRef<'span'> { 6 | /** The url of the icon. */ 7 | url: string; 8 | /** Whether the icon should be rendered monochrome. */ 9 | monochrome?: boolean; 10 | } 11 | 12 | export const Icon = forwardRef(function Icon(props, ref) { 13 | // eslint-disable-next-line @typescript-eslint/no-unused-vars 14 | const { children: ___, className, monochrome = true, url, ...others } = props; 15 | return ( 16 | 37 | ); 38 | }); 39 | -------------------------------------------------------------------------------- /website/components/Link.tsx: -------------------------------------------------------------------------------- 1 | import classnames from 'classnames'; 2 | import NextLink from 'next/link'; 3 | import { forwardRef, type ComponentPropsWithRef } from 'react'; 4 | 5 | export interface LinkProps extends ComponentPropsWithRef { 6 | external?: boolean; 7 | } 8 | 9 | // eslint-disable-next-line react/display-name 10 | export const Link = forwardRef(({ external, ...props }, ref) => { 11 | const className = classnames( 12 | 'no-underline text-primary-blue2 font-medium [background:linear-gradient(0deg,currentColor,currentColor)_no-repeat_right_bottom_/_0_2px]', 13 | '[transition:background-size_250ms] hover:[background-size:100%_2px] hover:[background-position-x:left]', 14 | 'focus-visible:rounded-sm', 15 | props.className 16 | ); 17 | 18 | return external ? ( 19 | // eslint-disable-next-line @typescript-eslint/no-explicit-any 20 | 21 | ) : ( 22 | 23 | ); 24 | }); 25 | -------------------------------------------------------------------------------- /website/components/OverlayScrollbarsClientComponent.tsx: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | export { OverlayScrollbarsComponent as OverlayScrollbarsClientComponent } from 'overlayscrollbars-react'; 3 | -------------------------------------------------------------------------------- /website/components/PageContainer.tsx: -------------------------------------------------------------------------------- 1 | import classnames from 'classnames'; 2 | import type { ReactNode } from 'react'; 3 | 4 | export interface PageContainerProps { 5 | children?: ReactNode; 6 | className?: string; 7 | } 8 | 9 | export const PageContainer = ({ children, className }: PageContainerProps) => ( 10 |
{children}
11 | ); 12 | -------------------------------------------------------------------------------- /website/mdx-components.tsx: -------------------------------------------------------------------------------- 1 | import { Link } from '~/components/Link'; 2 | import type { ComponentPropsWithoutRef } from 'react'; 3 | import type { MDXComponents } from 'mdx/types'; 4 | import { Heading, type HeadingProps } from './mdx/components/Heading'; 5 | import { Pre } from './mdx/components/Pre'; 6 | 7 | const generateHeading = (props: ComponentPropsWithoutRef<'h1'>, tag: HeadingProps['tag']) => ( 8 | // eslint-disable-next-line react/jsx-props-no-spreading 9 | 10 | ); 11 | 12 | export function useMDXComponents(components: MDXComponents): MDXComponents { 13 | return { 14 | ...components, 15 | h1: (props) => generateHeading(props, 'h1'), 16 | h2: (props) => generateHeading(props, 'h2'), 17 | h3: (props) => generateHeading(props, 'h3'), 18 | h4: (props) => generateHeading(props, 'h4'), 19 | h5: (props) => generateHeading(props, 'h5'), 20 | h6: (props) => generateHeading(props, 'h6'), 21 | a: (props) => , 22 | pre: Pre, 23 | }; 24 | } 25 | -------------------------------------------------------------------------------- /website/mdx/components/Heading.tsx: -------------------------------------------------------------------------------- 1 | // import Link from 'next/link'; 2 | import type { ComponentProps } from 'react'; 3 | 4 | export interface HeadingProps extends ComponentProps<'h1'> { 5 | tag: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6'; 6 | } 7 | 8 | export const Heading = ({ id, tag: Tag, ...rest }: HeadingProps) => { 9 | if (id) { 10 | return ( 11 | <> 12 | {/* */} 13 | {} 14 | 15 | {/* */} 16 | 17 | ); 18 | } 19 | 20 | return ; 21 | }; 22 | -------------------------------------------------------------------------------- /website/mdx/components/Pre.tsx: -------------------------------------------------------------------------------- 1 | import { OverlayScrollbarsClientComponent } from '~/components/OverlayScrollbarsClientComponent'; 2 | import type { ComponentProps } from 'react'; 3 | 4 | export const Pre = ({ children }: ComponentProps<'pre'>) => ( 5 | 13 | {children} 14 | 15 | ); 16 | -------------------------------------------------------------------------------- /website/next.config.js: -------------------------------------------------------------------------------- 1 | import mdx from '@next/mdx'; 2 | import rehypePrettyCode from 'rehype-pretty-code'; 3 | import rehypeSlug from 'rehype-slug'; 4 | import remarkGfm from 'remark-gfm'; 5 | 6 | const withMDX = mdx({ 7 | extension: /\.mdx?$/, 8 | options: { 9 | remarkPlugins: [remarkGfm], 10 | rehypePlugins: [ 11 | rehypeSlug, 12 | [ 13 | rehypePrettyCode, 14 | { 15 | theme: 'solarized-light', 16 | }, 17 | ], 18 | ], 19 | }, 20 | }); 21 | 22 | /** @type {import('next').NextConfig} */ 23 | const nextConfig = { 24 | reactStrictMode: true, 25 | swcMinify: true, 26 | output: 'export', 27 | distDir: 'dist', 28 | images: { 29 | unoptimized: true, 30 | }, 31 | pageExtensions: ['js', 'jsx', 'ts', 'tsx', 'md', 'mdx'], 32 | basePath: '/OverlayScrollbars', 33 | eslint: { 34 | ignoreDuringBuilds: true, 35 | }, 36 | }; 37 | 38 | export default withMDX(nextConfig); 39 | -------------------------------------------------------------------------------- /website/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "overlayscrollbars-docs", 3 | "version": "0.1.0", 4 | "type": "module", 5 | "private": true, 6 | "dependencies": { 7 | "@mdx-js/loader": "^3.0.1", 8 | "@mdx-js/react": "^3.0.1", 9 | "@next/mdx": "^14.2.5", 10 | "@types/node": "20.5.4", 11 | "@types/react": "18.2.21", 12 | "@types/react-dom": "18.2.7", 13 | "autoprefixer": "10.4.15", 14 | "classnames": "^2.3.2", 15 | "next": "14.2.5", 16 | "overlayscrollbars": "file:./../packages/overlayscrollbars/dist", 17 | "overlayscrollbars-react": "file:./../packages/overlayscrollbars-react/dist", 18 | "postcss": "8.4.28", 19 | "react": "18.2.0", 20 | "react-dom": "18.2.0", 21 | "tailwindcss": "3.3.3", 22 | "typescript": "5.1.6", 23 | "ua-parser-js": "^1.0.32" 24 | }, 25 | "devDependencies": { 26 | "@types/node": "18.7.20", 27 | "@types/react": "^18.2.45", 28 | "@types/react-dom": "^18.2.17", 29 | "@types/ua-parser-js": "^0.7.36", 30 | "rehype-pretty-code": "^0.13.0", 31 | "rehype-slug": "^6.0.0", 32 | "remark-gfm": "^4.0.0", 33 | "serve": "^14.2.1", 34 | "shiki": "^1.1.7", 35 | "tailwindcss": "^3.1.8", 36 | "typescript": "^5.0.0" 37 | }, 38 | "scripts": { 39 | "dev": "next dev", 40 | "build": "next build", 41 | "start": "serve dist/" 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /website/postcss.config.js: -------------------------------------------------------------------------------- 1 | export default { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | }; 7 | -------------------------------------------------------------------------------- /website/public/font/inter/inter-variable-slnt-wght.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KingSora/OverlayScrollbars/9cb3e2249f4be85e1e27753a85d20c00fc68cbda/website/public/font/inter/inter-variable-slnt-wght.ttf -------------------------------------------------------------------------------- /website/public/font/inter/inter-variable-slnt-wght.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KingSora/OverlayScrollbars/9cb3e2249f4be85e1e27753a85d20c00fc68cbda/website/public/font/inter/inter-variable-slnt-wght.woff2 -------------------------------------------------------------------------------- /website/public/icon/github.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /website/public/icon/javascript.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /website/public/img/adminlte-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KingSora/OverlayScrollbars/9cb3e2249f4be85e1e27753a85d20c00fc68cbda/website/public/img/adminlte-logo.png -------------------------------------------------------------------------------- /website/public/img/browserstack.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KingSora/OverlayScrollbars/9cb3e2249f4be85e1e27753a85d20c00fc68cbda/website/public/img/browserstack.png -------------------------------------------------------------------------------- /website/tailwind.config.js: -------------------------------------------------------------------------------- 1 | import tailwindPreset from '@~local/tailwind'; 2 | 3 | export default { 4 | presets: [tailwindPreset], 5 | content: [ 6 | './pages/**/*.{js,ts,jsx,tsx,mdx}', 7 | './components/**/*.{js,ts,jsx,tsx,mdx}', 8 | './mdx/**/*.{js,ts,jsx,tsx,mdx}', 9 | './app/**/*.{js,ts,jsx,tsx,mdx}', 10 | ], 11 | }; 12 | -------------------------------------------------------------------------------- /website/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "lib": [ 5 | "dom", 6 | "dom.iterable", 7 | "esnext" 8 | ], 9 | "allowJs": true, 10 | "skipLibCheck": true, 11 | "strict": true, 12 | "noEmit": true, 13 | "esModuleInterop": true, 14 | "module": "esnext", 15 | "moduleResolution": "bundler", 16 | "resolveJsonModule": true, 17 | "isolatedModules": true, 18 | "jsx": "preserve", 19 | "incremental": true, 20 | "plugins": [ 21 | { 22 | "name": "next" 23 | } 24 | ], 25 | "paths": { 26 | "~/*": [ 27 | "./*" 28 | ] 29 | } 30 | }, 31 | "include": [ 32 | "next-env.d.ts", 33 | "**/*.ts", 34 | "**/*.tsx", 35 | ".next/types/**/*.ts", 36 | "dist/types/**/*.ts" 37 | ], 38 | "exclude": [ 39 | "node_modules" 40 | ] 41 | } 42 | --------------------------------------------------------------------------------