├── .editorconfig ├── .eslintrc.json ├── .github ├── FUNDING.yml ├── ISSUE_TEMPLATE.md └── ISSUE_TEMPLATE │ ├── bug_report.md │ ├── feature_request.md │ └── questions.md ├── .gitignore ├── .nvmrc ├── .prettierrc ├── .travis.yml ├── CHANGELOG.md ├── LICENSE ├── README.md ├── examples ├── angular │ ├── .editorconfig │ ├── .gitignore │ ├── .vscode │ │ ├── extensions.json │ │ ├── launch.json │ │ └── tasks.json │ ├── README.md │ ├── angular.json │ ├── package.json │ ├── public │ │ └── favicon.ico │ ├── src │ │ ├── app │ │ │ ├── app.component.css │ │ │ ├── app.component.html │ │ │ ├── app.component.spec.ts │ │ │ ├── app.component.ts │ │ │ ├── app.config.ts │ │ │ └── app.routes.ts │ │ ├── index.html │ │ ├── main.ts │ │ └── styles.css │ ├── tsconfig.app.json │ ├── tsconfig.json │ ├── tsconfig.spec.json │ └── yarn.lock ├── jquery │ └── index.html ├── react │ ├── .gitignore │ ├── README.md │ ├── package.json │ ├── public │ │ ├── favicon.ico │ │ ├── index.html │ │ └── manifest.json │ ├── src │ │ ├── App.css │ │ ├── App.js │ │ ├── App.test.js │ │ ├── index.css │ │ ├── index.js │ │ ├── logo.svg │ │ └── registerServiceWorker.js │ └── yarn.lock ├── vue-2.7 │ ├── .babelrc │ ├── README.md │ ├── package.json │ ├── public │ │ └── index.html │ ├── src │ │ ├── App.vue │ │ └── main.js │ └── yarn.lock └── vue-3 │ ├── .babelrc │ ├── README.md │ ├── package.json │ ├── public │ └── index.html │ ├── src │ ├── App.vue │ └── main.js │ └── yarn.lock ├── jest-setup.ts ├── lerna.json ├── logo.eps ├── package.json ├── packages ├── examples │ ├── .babelrc │ ├── .eslintrc.json │ ├── .gitignore │ ├── Demo.js │ ├── Playground.js │ ├── bundle.js.LICENSE.txt │ ├── index.js │ ├── package.json │ ├── public │ │ ├── css │ │ │ ├── demo.css │ │ │ └── normalize.css │ │ └── index.html │ └── webpack.config.js ├── simplebar-angular │ ├── .editorconfig │ ├── .gitignore │ ├── CHANGELOG.md │ ├── README.md │ ├── angular.json │ ├── karma.conf.js │ ├── ng-package.json │ ├── package.json │ ├── src │ │ ├── lib │ │ │ ├── simplebar-angular.component.html │ │ │ ├── simplebar-angular.component.scss │ │ │ ├── simplebar-angular.component.spec.ts │ │ │ ├── simplebar-angular.component.ts │ │ │ └── simplebar-angular.module.ts │ │ └── public-api.ts │ ├── test-setup.ts │ ├── tsconfig.json │ ├── tsconfig.lib.json │ ├── tsconfig.lib.prod.json │ ├── tsconfig.spec.json │ └── tslint.json ├── simplebar-core │ ├── .babelrc.json │ ├── .gitignore │ ├── CHANGELOG.md │ ├── README.md │ ├── global-setup.js │ ├── global-teardown.js │ ├── jest-e2e.config.js │ ├── jest-puppeteer.config.js │ ├── jest-unit.config.js │ ├── package.json │ ├── rollup.config.mjs │ ├── src │ │ ├── helpers.ts │ │ ├── index.ts │ │ ├── scrollbar-width.ts │ │ └── simplebar.css │ └── tests │ │ ├── simplebar.test.e2e.js │ │ └── simplebar.test.ts ├── simplebar-react │ ├── .eslintrc.json │ ├── CHANGELOG.md │ ├── README.md │ ├── index.tsx │ ├── jest.config.js │ ├── package.json │ ├── rollup.config.mjs │ ├── tests │ │ ├── __snapshots__ │ │ │ └── index.test.tsx.snap │ │ └── index.test.tsx │ └── tsconfig.json ├── simplebar-vue │ ├── CHANGELOG.md │ ├── README.md │ ├── component.ts │ ├── index.ts │ ├── jest.config.js │ ├── package.json │ ├── rollup.config.mjs │ ├── scripts │ │ └── swap-vue.js │ ├── simplebar-vue.d.ts │ ├── tests │ │ ├── __snapshots__ │ │ │ └── index.test.ts.snap │ │ ├── index.test.ts │ │ └── test-utils.ts │ ├── tsconfig.json │ └── utils.ts ├── simplebar │ ├── .babelrc.json │ ├── .env │ ├── .gitignore │ ├── CHANGELOG.md │ ├── README.md │ ├── jest-unit.config.js │ ├── package.json │ ├── rollup.config.mjs │ ├── src │ │ └── index.ts │ └── tests │ │ └── simplebar.test.js └── website │ ├── .gitignore │ ├── .prettierignore │ ├── .prettierrc │ ├── LICENSE │ ├── README.md │ ├── gatsby-browser.js │ ├── gatsby-config.js │ ├── gatsby-node.js │ ├── gatsby-ssr.js │ ├── package.json │ └── src │ ├── components │ ├── Layout.js │ ├── List.js │ ├── Playground.js │ └── SEO.js │ ├── demo.css │ ├── html.js │ ├── images │ ├── browserstack.png │ ├── favicon.svg │ ├── logo.svg │ └── users │ │ ├── storybook.svg │ │ ├── twitch.svg │ │ └── zulip.svg │ ├── pages │ ├── 404.js │ ├── examples.js │ └── index.js │ └── theme.js ├── rollup.config.mjs ├── tsconfig.json ├── web.sketch └── yarn.lock /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | end_of_line = lf 6 | insert_final_newline = true 7 | trim_trailing_whitespace = true 8 | indent_style = space 9 | 10 | [**.js] 11 | indent_size = 2 12 | 13 | [**.css] 14 | indent_size = 2 15 | 16 | [**.html] 17 | indent_size = 2 18 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "extends": [ 4 | "eslint:recommended" 5 | ], 6 | "env": { 7 | "browser": true, 8 | "node": true, 9 | "es2020": true 10 | }, 11 | "parserOptions": { 12 | "sourceType": "module", 13 | "ecmaVersion": 2018 14 | }, 15 | "overrides": [ 16 | { 17 | "files": ["**/*.ts", "**/*.tsx"], 18 | "parser": "@typescript-eslint/parser", 19 | "extends": ["eslint:recommended", "plugin:@typescript-eslint/recommended"], 20 | "plugins": ["@typescript-eslint"] 21 | }, 22 | { 23 | "files": ["**/*.test?(.*).ts", "**/*.test?(.*).tsx", "**/*.test?(.*).js"], 24 | "env": { 25 | "jest": true, 26 | "jest/globals": true 27 | }, 28 | "globals": { 29 | "page": true, 30 | "browser": true, 31 | "context": true, 32 | "jestPuppeteer": true 33 | }, 34 | "plugins": ["jest"] 35 | } 36 | ] 37 | } 38 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: grsmto 2 | buy_me_a_coffee: adriendenat 3 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ## 🔎 Usage Questions 2 | 3 | Before you ask a question, please make sure you've: 4 | 5 | - Looked for prior or closed issues 6 | - Checked the README 7 | - Looked for/asked questions on stack overflow: https://stackoverflow.com/search?q=simplebar 8 | 9 | ## ✨ Feature Requests 10 | 11 | SimpleBar's mission statement is to keep things simple and stick to the native scroll behaviour as much as possible. However if you have a suggestion that falls within this approach that hasn't already been proposed, we'd love to hear it! 12 | 13 | ## 🐛 Bugs 14 | 15 | Please complete the following template: 16 | 17 | ## Current Behavior 18 | 19 | 20 | 21 | ## Expected behavior 22 | 23 | 24 | 25 | ## Reproducible example 26 | 27 | 28 | 29 | ## Suggested solution(s) 30 | 31 | 32 | 33 | ## Additional context 34 | 35 | 36 | 37 | ## Your environment 38 | 39 | | Software | Version(s) | 40 | | ---------------- | ---------- | 41 | | SimpleBar | 42 | | Browser | 43 | | npm/Yarn | 44 | | Operating System | 45 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 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 | **Reproducible example** 24 | 25 | 26 | **Additional context** 27 | Add any other context about the problem here. 28 | 29 | **Your environment** 30 | 31 | | Software | Version(s) | 32 | | ---------------- | ---------- | 33 | | SimpleBar | 34 | | Browser | 35 | | npm/Yarn | 36 | | Operating System | 37 | -------------------------------------------------------------------------------- /.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 | 10 | SimpleBar's mission statement is to keep things simple and stick to the native scroll behaviour as much as possible. However if you have a suggestion that falls within this approach that hasn't already been proposed, we'd love to hear it! 11 | 12 | **Is your feature request related to a problem? Please describe.** 13 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 14 | 15 | **Describe the solution you'd like** 16 | A clear and concise description of what you want to happen. 17 | 18 | **Describe alternatives you've considered** 19 | A clear and concise description of any alternative solutions or features you've considered. 20 | 21 | **Additional context** 22 | Add any other context or screenshots about the feature request here. 23 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/questions.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Questions / Help 3 | about: If you have questions, please read full readme first 4 | title: '' 5 | labels: question 6 | assignees: '' 7 | 8 | --- 9 | 10 | ## 💬 Questions and Help 11 | 12 | Please before asking your question: 13 | 14 | - Read carefully the README of the project 15 | - Search if your answer has already been answered in old issues 16 | 17 | After you can submit your question and we will be happy to help you! 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | .temp 4 | dist 5 | yarn-error.log 6 | .next 7 | .env 8 | .idea 9 | yalc.lock 10 | .yalc 11 | local.log 12 | -------------------------------------------------------------------------------- /.nvmrc: -------------------------------------------------------------------------------- 1 | 20.11.1 2 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true 3 | } 4 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | cache: yarn 3 | 4 | before_install: 5 | - npm i -g lerna 6 | 7 | install: 8 | - yarn 9 | 10 | script: 11 | - yarn build 12 | - yarn test 13 | 14 | deploy: 15 | provider: script 16 | skip_cleanup: true 17 | script: cd packages/website/ && yarn deploy 18 | on: 19 | branch: master 20 | 21 | addons: 22 | chrome: stable 23 | browserstack: 24 | username: 'adriengrsmto' 25 | access_key: 26 | secure: 'HUmCxQG5gsOak0EFqAHTlIBlPL2lLjbKTaYQ0rAEFMu0E4WknH5z1qqZdw9ntAo201u+Pk/jC+YmPqSF3TjpxE5vOqeVCU27YSoUhZid1iI43z7uquuiXXsBlsaQZ0o2PNDSRoWTJ9G5Dfn+YgOIyEnFYEucAIii+tLo2lZVhlY=' 27 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Jonathan Nicol 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. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 4 | 5 | 11 | 12 | 13 | SimpleBar does only one thing: replace the browser's default scrollbar with a custom CSS-styled one without losing performances. 14 | Unlike some popular plugins, SimpleBar doesn't mimic scroll with Javascript, causing janks and strange scrolling behaviours... 15 | You keep the awesomeness of native scrolling...with a custom scrollbar! 16 | SimpleBar **does NOT implement a custom scroll behaviour**. It keeps the **native** `overflow: auto` scroll and **only** replace the scrollbar visual appearance. 17 | 18 | - **🐦 Follow me on [Twitter!](https://twitter.com/adriendenat) or [Mastodon!](https://mas.to/@adrien)** 19 | - **👨‍💻 If you like Simplebar, [buy me a coffee!](adriendenat)** 20 | 21 | Buy Me A Coffee 22 | 23 | #### Design it as you want 24 | 25 | SimpleBar uses pure CSS to style the scrollbar. You can easily customize it as you want! Or even have multiple style on the same page...or just keep the default style ("Mac OS" scrollbar style). 26 | 27 | #### Lightweight and performant 28 | 29 | Only 6kb minified. SimpleBar doesn't use Javascript to handle scrolling. You keep the performances/behaviours of the native scroll. 30 | 31 | #### Supported everywhere 32 | 33 | SimpleBar has been tested on the following browsers: Chrome, Firefox, Safari, Edge, IE11. 34 | 35 | ### Getting started 36 | 37 | The easiest way to use SimpleBar is with the default dependency-free version: `npm install simplebar`. 38 | 39 | - [Core documention](https://github.com/Grsmto/simplebar/tree/master/packages/simplebar) 40 | 41 | If you are using a framework, SimpleBar also supports the most popular ones: Vue, Angular and React. 42 | 43 | - [React documention](https://github.com/Grsmto/simplebar/tree/master/packages/simplebar-react) 44 | - [Angular documentation](https://github.com/Grsmto/simplebar/tree/master/packages/simplebar-angular) 45 | - [Vue documentation](https://github.com/Grsmto/simplebar/tree/master/packages/simplebar-vue) 46 | 47 | ### Demo 48 | 49 | You can check our [demo page](https://grsmto.github.io/simplebar/examples) (which is also the one we use for automated tests). 50 | 51 | ### Changelog 52 | 53 | See changelog here : https://github.com/Grsmto/simplebar/releases 54 | 55 | ### Credits 56 | 57 | - [KingSora](https://github.com/KingSora) for multiple features and inspirations (`height: auto` detection, RTL mode cross browser support and more) with [OverlayScrollbars](https://kingsora.github.io/OverlayScrollbars/). 58 | - [Jonathan Nicol](http://www.f6design.com/) for original idea with [Trackpad Scroll Emulator](https://github.com/jnicol/trackpad-scroll-emulator). 59 | - [Cassio Bittencourt](https://cassiobittencourt.com/) for the logo design. 60 | -------------------------------------------------------------------------------- /examples/angular/.editorconfig: -------------------------------------------------------------------------------- 1 | # Editor configuration, see https://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 2 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.ts] 12 | quote_type = single 13 | 14 | [*.md] 15 | max_line_length = off 16 | trim_trailing_whitespace = false 17 | -------------------------------------------------------------------------------- /examples/angular/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://docs.github.com/get-started/getting-started-with-git/ignoring-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/cache 33 | .sass-cache/ 34 | /connect.lock 35 | /coverage 36 | /libpeerconnection.log 37 | testem.log 38 | /typings 39 | 40 | # System files 41 | .DS_Store 42 | Thumbs.db 43 | -------------------------------------------------------------------------------- /examples/angular/.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=827846 3 | "recommendations": ["angular.ng-template"] 4 | } 5 | -------------------------------------------------------------------------------- /examples/angular/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 3 | "version": "0.2.0", 4 | "configurations": [ 5 | { 6 | "name": "ng serve", 7 | "type": "chrome", 8 | "request": "launch", 9 | "preLaunchTask": "npm: start", 10 | "url": "http://localhost:4200/" 11 | }, 12 | { 13 | "name": "ng test", 14 | "type": "chrome", 15 | "request": "launch", 16 | "preLaunchTask": "npm: test", 17 | "url": "http://localhost:9876/debug.html" 18 | } 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /examples/angular/.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | // For more information, visit: https://go.microsoft.com/fwlink/?LinkId=733558 3 | "version": "2.0.0", 4 | "tasks": [ 5 | { 6 | "type": "npm", 7 | "script": "start", 8 | "isBackground": true, 9 | "problemMatcher": { 10 | "owner": "typescript", 11 | "pattern": "$tsc", 12 | "background": { 13 | "activeOnStart": true, 14 | "beginsPattern": { 15 | "regexp": "(.*?)" 16 | }, 17 | "endsPattern": { 18 | "regexp": "bundle generation complete" 19 | } 20 | } 21 | } 22 | }, 23 | { 24 | "type": "npm", 25 | "script": "test", 26 | "isBackground": true, 27 | "problemMatcher": { 28 | "owner": "typescript", 29 | "pattern": "$tsc", 30 | "background": { 31 | "activeOnStart": true, 32 | "beginsPattern": { 33 | "regexp": "(.*?)" 34 | }, 35 | "endsPattern": { 36 | "regexp": "bundle generation complete" 37 | } 38 | } 39 | } 40 | } 41 | ] 42 | } 43 | -------------------------------------------------------------------------------- /examples/angular/README.md: -------------------------------------------------------------------------------- 1 | # angular 2 | 3 | This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 18.0.4. 4 | 5 | ## Development server 6 | 7 | Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The application will automatically reload if you change any of the source files. 8 | 9 | ## Code scaffolding 10 | 11 | Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`. 12 | 13 | ## Build 14 | 15 | Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. 16 | 17 | ## Running unit tests 18 | 19 | Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io). 20 | 21 | ## Running end-to-end tests 22 | 23 | Run `ng e2e` to execute the end-to-end tests via a platform of your choice. To use this command, you need to first add a package that implements end-to-end testing capabilities. 24 | 25 | ## Further help 26 | 27 | To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI Overview and Command Reference](https://angular.dev/tools/cli) page. 28 | -------------------------------------------------------------------------------- /examples/angular/angular.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "./node_modules/@angular/cli/lib/config/schema.json", 3 | "version": 1, 4 | "newProjectRoot": "projects", 5 | "projects": { 6 | "angular": { 7 | "projectType": "application", 8 | "schematics": {}, 9 | "root": "", 10 | "sourceRoot": "src", 11 | "prefix": "app", 12 | "architect": { 13 | "build": { 14 | "builder": "@angular-devkit/build-angular:application", 15 | "options": { 16 | "outputPath": "dist/angular", 17 | "index": "src/index.html", 18 | "browser": "src/main.ts", 19 | "polyfills": ["zone.js"], 20 | "tsConfig": "tsconfig.app.json", 21 | "assets": [ 22 | { 23 | "glob": "**/*", 24 | "input": "public" 25 | } 26 | ], 27 | "styles": ["src/styles.css"], 28 | "scripts": [], 29 | "preserveSymlinks": true 30 | }, 31 | "configurations": { 32 | "production": { 33 | "budgets": [ 34 | { 35 | "type": "initial", 36 | "maximumWarning": "500kB", 37 | "maximumError": "1MB" 38 | }, 39 | { 40 | "type": "anyComponentStyle", 41 | "maximumWarning": "2kB", 42 | "maximumError": "4kB" 43 | } 44 | ], 45 | "outputHashing": "all" 46 | }, 47 | "development": { 48 | "optimization": false, 49 | "extractLicenses": false, 50 | "sourceMap": true 51 | } 52 | }, 53 | "defaultConfiguration": "production" 54 | }, 55 | "serve": { 56 | "builder": "@angular-devkit/build-angular:dev-server", 57 | "configurations": { 58 | "production": { 59 | "buildTarget": "angular:build:production" 60 | }, 61 | "development": { 62 | "buildTarget": "angular:build:development" 63 | } 64 | }, 65 | "defaultConfiguration": "development" 66 | }, 67 | "extract-i18n": { 68 | "builder": "@angular-devkit/build-angular:extract-i18n" 69 | }, 70 | "test": { 71 | "builder": "@angular-devkit/build-angular:karma", 72 | "options": { 73 | "polyfills": ["zone.js", "zone.js/testing"], 74 | "tsConfig": "tsconfig.spec.json", 75 | "assets": [ 76 | { 77 | "glob": "**/*", 78 | "input": "public" 79 | } 80 | ], 81 | "styles": ["src/styles.css"], 82 | "scripts": [] 83 | } 84 | } 85 | } 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /examples/angular/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "angular", 3 | "version": "0.0.0", 4 | "scripts": { 5 | "ng": "ng", 6 | "start": "ng serve", 7 | "build": "ng build", 8 | "watch": "ng build --watch --configuration development", 9 | "test": "ng test" 10 | }, 11 | "private": true, 12 | "dependencies": { 13 | "@angular/animations": "^18.0.0", 14 | "@angular/common": "^18.0.0", 15 | "@angular/compiler": "^18.0.0", 16 | "@angular/core": "^18.0.0", 17 | "@angular/forms": "^18.0.0", 18 | "@angular/platform-browser": "^18.0.0", 19 | "@angular/platform-browser-dynamic": "^18.0.0", 20 | "@angular/router": "^18.0.0", 21 | "rxjs": "~7.8.0", 22 | "simplebar-angular": "latest", 23 | "tslib": "^2.3.0", 24 | "zone.js": "~0.14.3" 25 | }, 26 | "devDependencies": { 27 | "@angular-devkit/build-angular": "^18.0.4", 28 | "@angular/cli": "^18.0.4", 29 | "@angular/compiler-cli": "^18.0.3", 30 | "@types/jasmine": "~5.1.4", 31 | "jasmine-core": "~5.1.0", 32 | "karma": "~6.4.3", 33 | "karma-chrome-launcher": "~3.2.0", 34 | "karma-coverage": "~2.2.1", 35 | "karma-jasmine": "~5.1.0", 36 | "karma-jasmine-html-reporter": "~2.1.0", 37 | "typescript": "~5.4.2" 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /examples/angular/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Grsmto/simplebar/3885152e72af29662d613dca32f7b76d4120f184/examples/angular/public/favicon.ico -------------------------------------------------------------------------------- /examples/angular/src/app/app.component.css: -------------------------------------------------------------------------------- 1 | .container { 2 | border-radius: 6px; 3 | width: 200px; 4 | height: 200px; 5 | position: absolute; 6 | top: 0; 7 | left: 0; 8 | right: 0; 9 | bottom: 0; 10 | border: 1px dashed; 11 | margin: auto; 12 | } 13 | 14 | ngx-simplebar { 15 | height: 100%; 16 | } 17 | -------------------------------------------------------------------------------- /examples/angular/src/app/app.component.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 179 | 180 |
181 |
182 | 183 |
ngx-simplebar
184 |
185 |
186 |
187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | -------------------------------------------------------------------------------- /examples/angular/src/app/app.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed } from '@angular/core/testing'; 2 | import { AppComponent } from './app.component'; 3 | 4 | describe('AppComponent', () => { 5 | beforeEach(async () => { 6 | await TestBed.configureTestingModule({ 7 | imports: [AppComponent], 8 | }).compileComponents(); 9 | }); 10 | 11 | it('should create the app', () => { 12 | const fixture = TestBed.createComponent(AppComponent); 13 | const app = fixture.componentInstance; 14 | expect(app).toBeTruthy(); 15 | }); 16 | 17 | it(`should have the 'angular' title`, () => { 18 | const fixture = TestBed.createComponent(AppComponent); 19 | const app = fixture.componentInstance; 20 | expect(app.title).toEqual('angular'); 21 | }); 22 | 23 | it('should render title', () => { 24 | const fixture = TestBed.createComponent(AppComponent); 25 | fixture.detectChanges(); 26 | const compiled = fixture.nativeElement as HTMLElement; 27 | expect(compiled.querySelector('h1')?.textContent).toContain( 28 | 'Hello, angular' 29 | ); 30 | }); 31 | }); 32 | -------------------------------------------------------------------------------- /examples/angular/src/app/app.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | import { RouterOutlet } from '@angular/router'; 3 | import { NgFor } from '@angular/common'; 4 | import { SimplebarAngularModule } from 'simplebar-angular'; 5 | 6 | @Component({ 7 | selector: 'app-root', 8 | standalone: true, 9 | imports: [RouterOutlet, SimplebarAngularModule, NgFor], 10 | templateUrl: './app.component.html', 11 | styleUrl: './app.component.css', 12 | }) 13 | export class AppComponent { 14 | title = 'angular'; 15 | numbers = Array(50).fill(0); 16 | options = { autoHide: false }; 17 | } 18 | -------------------------------------------------------------------------------- /examples/angular/src/app/app.config.ts: -------------------------------------------------------------------------------- 1 | import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core'; 2 | import { provideRouter } from '@angular/router'; 3 | 4 | import { routes } from './app.routes'; 5 | 6 | export const appConfig: ApplicationConfig = { 7 | providers: [provideZoneChangeDetection({ eventCoalescing: true }), provideRouter(routes)] 8 | }; 9 | -------------------------------------------------------------------------------- /examples/angular/src/app/app.routes.ts: -------------------------------------------------------------------------------- 1 | import { Routes } from '@angular/router'; 2 | 3 | export const routes: Routes = []; 4 | -------------------------------------------------------------------------------- /examples/angular/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | angular 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /examples/angular/src/main.ts: -------------------------------------------------------------------------------- 1 | import { bootstrapApplication } from '@angular/platform-browser'; 2 | import { appConfig } from './app/app.config'; 3 | import { AppComponent } from './app/app.component'; 4 | 5 | bootstrapApplication(AppComponent, appConfig).catch((err) => 6 | console.error(err) 7 | ); 8 | -------------------------------------------------------------------------------- /examples/angular/src/styles.css: -------------------------------------------------------------------------------- 1 | /* You can add global styles to this file, and also import other style files */ 2 | -------------------------------------------------------------------------------- /examples/angular/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | /* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ 2 | /* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ 3 | { 4 | "extends": "./tsconfig.json", 5 | "compilerOptions": { 6 | "outDir": "./out-tsc/app", 7 | "types": [] 8 | }, 9 | "files": [ 10 | "src/main.ts" 11 | ], 12 | "include": [ 13 | "src/**/*.d.ts" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /examples/angular/tsconfig.json: -------------------------------------------------------------------------------- 1 | /* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ 2 | /* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ 3 | { 4 | "compileOnSave": false, 5 | "compilerOptions": { 6 | "outDir": "./dist/out-tsc", 7 | "strict": true, 8 | "noImplicitOverride": true, 9 | "noPropertyAccessFromIndexSignature": true, 10 | "noImplicitReturns": true, 11 | "noFallthroughCasesInSwitch": true, 12 | "skipLibCheck": true, 13 | "esModuleInterop": true, 14 | "sourceMap": true, 15 | "declaration": false, 16 | "experimentalDecorators": true, 17 | "moduleResolution": "bundler", 18 | "importHelpers": true, 19 | "target": "ES2022", 20 | "module": "ES2022", 21 | "useDefineForClassFields": false, 22 | "lib": [ 23 | "ES2022", 24 | "dom" 25 | ] 26 | }, 27 | "angularCompilerOptions": { 28 | "enableI18nLegacyMessageIdFormat": false, 29 | "strictInjectionParameters": true, 30 | "strictInputAccessModifiers": true, 31 | "strictTemplates": true 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /examples/angular/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | /* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ 2 | /* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ 3 | { 4 | "extends": "./tsconfig.json", 5 | "compilerOptions": { 6 | "outDir": "./out-tsc/spec", 7 | "types": [ 8 | "jasmine" 9 | ] 10 | }, 11 | "include": [ 12 | "src/**/*.spec.ts", 13 | "src/**/*.d.ts" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /examples/jquery/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 17 | 18 | 25 | 26 | 27 |
28 |

↓Scrollable!↓

29 |

↓Scrollable!↓

30 |

↓Scrollable!↓

31 |

↓Scrollable!↓

32 |

↓Scrollable!↓

33 |
34 | 35 | 36 | -------------------------------------------------------------------------------- /examples/react/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | 6 | # testing 7 | /coverage 8 | 9 | # production 10 | /build 11 | 12 | # misc 13 | .DS_Store 14 | .env.local 15 | .env.development.local 16 | .env.test.local 17 | .env.production.local 18 | 19 | npm-debug.log* 20 | yarn-debug.log* 21 | yarn-error.log* 22 | -------------------------------------------------------------------------------- /examples/react/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "my-app", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "react": "^16.4.1", 7 | "react-dom": "^16.4.1", 8 | "react-scripts": "latest", 9 | "simplebar-react": "latest" 10 | }, 11 | "scripts": { 12 | "start": "react-scripts start", 13 | "build": "react-scripts build", 14 | "test": "react-scripts test --env=jsdom", 15 | "eject": "react-scripts eject" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /examples/react/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Grsmto/simplebar/3885152e72af29662d613dca32f7b76d4120f184/examples/react/public/favicon.ico -------------------------------------------------------------------------------- /examples/react/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 11 | 12 | 13 | 22 | React App 23 | 24 | 25 | 28 |
29 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /examples/react/public/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": "./index.html", 12 | "display": "standalone", 13 | "theme_color": "#000000", 14 | "background_color": "#ffffff" 15 | } 16 | -------------------------------------------------------------------------------- /examples/react/src/App.css: -------------------------------------------------------------------------------- 1 | .App { 2 | text-align: center; 3 | } 4 | 5 | .App-logo { 6 | animation: App-logo-spin infinite 20s linear; 7 | height: 80px; 8 | } 9 | 10 | .App-header { 11 | background-color: #222; 12 | height: 150px; 13 | padding: 20px; 14 | color: white; 15 | } 16 | 17 | .App-title { 18 | font-size: 1.5em; 19 | } 20 | 21 | .App-intro { 22 | font-size: large; 23 | } 24 | 25 | @keyframes App-logo-spin { 26 | from { transform: rotate(0deg); } 27 | to { transform: rotate(360deg); } 28 | } 29 | -------------------------------------------------------------------------------- /examples/react/src/App.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import SimpleBar from 'simplebar-react'; 3 | 4 | import 'simplebar-react/dist/simplebar.min.css'; 5 | import logo from './logo.svg'; 6 | import './App.css'; 7 | 8 | class App extends Component { 9 | render() { 10 | return ( 11 |
12 |
13 | logo 14 |

Welcome to React

15 |
16 |

17 | To get started, edit src/App.js and save to reload. 18 |

19 | 20 | {[...Array(50)].map((x, i) => 21 |

Some content

22 | )} 23 |
24 |
25 | ); 26 | } 27 | } 28 | 29 | export default App; 30 | -------------------------------------------------------------------------------- /examples/react/src/App.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import App from './App'; 4 | 5 | it('renders without crashing', () => { 6 | const div = document.createElement('div'); 7 | ReactDOM.render(, div); 8 | ReactDOM.unmountComponentAtNode(div); 9 | }); 10 | -------------------------------------------------------------------------------- /examples/react/src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | padding: 0; 4 | font-family: sans-serif; 5 | } 6 | -------------------------------------------------------------------------------- /examples/react/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import './index.css'; 4 | import App from './App'; 5 | import registerServiceWorker from './registerServiceWorker'; 6 | 7 | ReactDOM.render(, document.getElementById('root')); 8 | registerServiceWorker(); 9 | -------------------------------------------------------------------------------- /examples/react/src/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /examples/react/src/registerServiceWorker.js: -------------------------------------------------------------------------------- 1 | // In production, we register a service worker to serve assets from local cache. 2 | 3 | // This lets the app load faster on subsequent visits in production, and gives 4 | // it offline capabilities. However, it also means that developers (and users) 5 | // will only see deployed updates on the "N+1" visit to a page, since previously 6 | // cached resources are updated in the background. 7 | 8 | // To learn more about the benefits of this model, read https://goo.gl/KwvDNy. 9 | // This link also includes instructions on opting out of this behavior. 10 | 11 | const isLocalhost = Boolean( 12 | window.location.hostname === 'localhost' || 13 | // [::1] is the IPv6 localhost address. 14 | window.location.hostname === '[::1]' || 15 | // 127.0.0.1/8 is considered localhost for IPv4. 16 | window.location.hostname.match( 17 | /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/ 18 | ) 19 | ); 20 | 21 | export default function register() { 22 | if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) { 23 | // The URL constructor is available in all browsers that support SW. 24 | const publicUrl = new URL(process.env.PUBLIC_URL, window.location); 25 | if (publicUrl.origin !== window.location.origin) { 26 | // Our service worker won't work if PUBLIC_URL is on a different origin 27 | // from what our page is served on. This might happen if a CDN is used to 28 | // serve assets; see https://github.com/facebookincubator/create-react-app/issues/2374 29 | return; 30 | } 31 | 32 | window.addEventListener('load', () => { 33 | const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`; 34 | 35 | if (isLocalhost) { 36 | // This is running on localhost. Lets check if a service worker still exists or not. 37 | checkValidServiceWorker(swUrl); 38 | 39 | // Add some additional logging to localhost, pointing developers to the 40 | // service worker/PWA documentation. 41 | navigator.serviceWorker.ready.then(() => { 42 | console.log( 43 | 'This web app is being served cache-first by a service ' + 44 | 'worker. To learn more, visit https://goo.gl/SC7cgQ' 45 | ); 46 | }); 47 | } else { 48 | // Is not local host. Just register service worker 49 | registerValidSW(swUrl); 50 | } 51 | }); 52 | } 53 | } 54 | 55 | function registerValidSW(swUrl) { 56 | navigator.serviceWorker 57 | .register(swUrl) 58 | .then(registration => { 59 | registration.onupdatefound = () => { 60 | const installingWorker = registration.installing; 61 | installingWorker.onstatechange = () => { 62 | if (installingWorker.state === 'installed') { 63 | if (navigator.serviceWorker.controller) { 64 | // At this point, the old content will have been purged and 65 | // the fresh content will have been added to the cache. 66 | // It's the perfect time to display a "New content is 67 | // available; please refresh." message in your web app. 68 | console.log('New content is available; please refresh.'); 69 | } else { 70 | // At this point, everything has been precached. 71 | // It's the perfect time to display a 72 | // "Content is cached for offline use." message. 73 | console.log('Content is cached for offline use.'); 74 | } 75 | } 76 | }; 77 | }; 78 | }) 79 | .catch(error => { 80 | console.error('Error during service worker registration:', error); 81 | }); 82 | } 83 | 84 | function checkValidServiceWorker(swUrl) { 85 | // Check if the service worker can be found. If it can't reload the page. 86 | fetch(swUrl) 87 | .then(response => { 88 | // Ensure service worker exists, and that we really are getting a JS file. 89 | if ( 90 | response.status === 404 || 91 | response.headers.get('content-type').indexOf('javascript') === -1 92 | ) { 93 | // No service worker found. Probably a different app. Reload the page. 94 | navigator.serviceWorker.ready.then(registration => { 95 | registration.unregister().then(() => { 96 | window.location.reload(); 97 | }); 98 | }); 99 | } else { 100 | // Service worker found. Proceed as normal. 101 | registerValidSW(swUrl); 102 | } 103 | }) 104 | .catch(() => { 105 | console.log( 106 | 'No internet connection found. App is running in offline mode.' 107 | ); 108 | }); 109 | } 110 | 111 | export function unregister() { 112 | if ('serviceWorker' in navigator) { 113 | navigator.serviceWorker.ready.then(registration => { 114 | registration.unregister(); 115 | }); 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /examples/vue-2.7/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | "vue" 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /examples/vue-2.7/README.md: -------------------------------------------------------------------------------- 1 | # SimpleBar Vue Example 2 | 3 | ## Project setup 4 | ``` 5 | npm install 6 | ``` 7 | 8 | ### Compiles and hot-reloads for development 9 | ``` 10 | npm run serve 11 | ``` 12 | 13 | ### Compiles and minifies for production 14 | ``` 15 | npm run build 16 | ``` 17 | 18 | ### Run your tests 19 | ``` 20 | npm run test 21 | ``` 22 | 23 | ### Lints and fixes files 24 | ``` 25 | npm run lint 26 | ``` 27 | -------------------------------------------------------------------------------- /examples/vue-2.7/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-simplebar-example", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "serve": "vue-cli-service serve", 7 | "build": "vue-cli-service build", 8 | "lint": "vue-cli-service lint" 9 | }, 10 | "dependencies": { 11 | "babel-preset-vue": "^2.0.2", 12 | "simplebar-vue": "file:../../packages/simplebar-vue", 13 | "vue": "2.7.14" 14 | }, 15 | "devDependencies": { 16 | "@vue/cli-plugin-babel": "^3.0.5", 17 | "@vue/cli-plugin-eslint": "^3.0.5", 18 | "@vue/cli-service": "^3.0.5", 19 | "vue-template-compiler": "2.7.14" 20 | }, 21 | "eslintConfig": { 22 | "root": true, 23 | "env": { 24 | "node": true 25 | }, 26 | "extends": [ 27 | "plugin:vue/essential", 28 | "eslint:recommended" 29 | ], 30 | "rules": {}, 31 | "parserOptions": { 32 | "parser": "babel-eslint" 33 | } 34 | }, 35 | "postcss": { 36 | "plugins": { 37 | "autoprefixer": {} 38 | } 39 | }, 40 | "browserslist": [ 41 | "> 1%", 42 | "last 2 versions", 43 | "not ie <= 8" 44 | ] 45 | } 46 | -------------------------------------------------------------------------------- /examples/vue-2.7/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | SimpleBar Vue Example 8 | 9 | 10 | 13 |
14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /examples/vue-2.7/src/App.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 24 | 25 | 30 | -------------------------------------------------------------------------------- /examples/vue-2.7/src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue'; 2 | import App from './App.vue'; 3 | 4 | Vue.config.productionTip = false; 5 | 6 | new Vue({ 7 | render: h => h(App) 8 | }).$mount('#app'); 9 | -------------------------------------------------------------------------------- /examples/vue-3/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | "vue" 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /examples/vue-3/README.md: -------------------------------------------------------------------------------- 1 | # SimpleBar Vue Example 2 | 3 | ## Project setup 4 | ``` 5 | npm install 6 | ``` 7 | 8 | ### Compiles and hot-reloads for development 9 | ``` 10 | npm run serve 11 | ``` 12 | 13 | ### Compiles and minifies for production 14 | ``` 15 | npm run build 16 | ``` 17 | 18 | ### Run your tests 19 | ``` 20 | npm run test 21 | ``` 22 | 23 | ### Lints and fixes files 24 | ``` 25 | npm run lint 26 | ``` 27 | -------------------------------------------------------------------------------- /examples/vue-3/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-v3-simplebar-example", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "serve": "vue-cli-service serve", 7 | "build": "vue-cli-service build", 8 | "lint": "vue-cli-service lint" 9 | }, 10 | "dependencies": { 11 | "babel-preset-vue": "^2.0.2", 12 | "simplebar-vue": "../../packages/simplebar-vue", 13 | "vue": "^3.2.45" 14 | }, 15 | "devDependencies": { 16 | "@vue/cli-plugin-babel": "^5.0.8", 17 | "@vue/cli-plugin-eslint": "^5.0.8", 18 | "@vue/cli-service": "^5.0.8", 19 | "eslint-plugin-vue": "^9.8.0", 20 | "vue-template-compiler": "^2.7.14" 21 | }, 22 | "eslintConfig": { 23 | "root": true, 24 | "env": { 25 | "node": true 26 | }, 27 | "extends": [ 28 | "plugin:vue/essential", 29 | "eslint:recommended" 30 | ], 31 | "rules": {}, 32 | "parserOptions": { 33 | "parser": "babel-eslint" 34 | } 35 | }, 36 | "postcss": { 37 | "plugins": { 38 | "autoprefixer": {} 39 | } 40 | }, 41 | "browserslist": [ 42 | "> 1%", 43 | "last 2 versions", 44 | "not ie <= 8" 45 | ] 46 | } 47 | -------------------------------------------------------------------------------- /examples/vue-3/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | SimpleBar Vue Example 8 | 9 | 10 | 13 |
14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /examples/vue-3/src/App.vue: -------------------------------------------------------------------------------- 1 | 5 | 6 | 13 | 14 | 24 | -------------------------------------------------------------------------------- /examples/vue-3/src/main.js: -------------------------------------------------------------------------------- 1 | import { createApp } from 'vue'; 2 | import App from './App.vue'; 3 | 4 | createApp(App).mount('#app'); 5 | -------------------------------------------------------------------------------- /jest-setup.ts: -------------------------------------------------------------------------------- 1 | import '@testing-library/jest-dom'; 2 | -------------------------------------------------------------------------------- /lerna.json: -------------------------------------------------------------------------------- 1 | { 2 | "lerna": "2.11.0", 3 | "version": "independent", 4 | "npmClient": "yarn", 5 | "useWorkspaces": true, 6 | "ignoreChanges": ["**/demo/**", "**/*.md"] 7 | } 8 | -------------------------------------------------------------------------------- /logo.eps: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Grsmto/simplebar/3885152e72af29662d613dca32f7b76d4120f184/logo.eps -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "workspaces": { 4 | "packages": [ 5 | "packages/*" 6 | ], 7 | "nohoist": [ 8 | "**/webpack/**", 9 | "**/webpack-dev-server/**", 10 | "**/webpack-cli/**" 11 | ] 12 | }, 13 | "scripts": { 14 | "build": "lerna exec yarn build", 15 | "test": "lerna run test", 16 | "release": "yarn build && yarn test && auto changelog && lerna publish --pre-dist-tag beta --preid beta", 17 | "start": "lerna exec --scope=simplebar yarn start", 18 | "dev": "lerna exec --scope=simplebar yarn dev" 19 | }, 20 | "devDependencies": { 21 | "@babel/core": "^7.20.7", 22 | "@babel/preset-env": "^7.20.2", 23 | "@babel/preset-react": "^7.18.6", 24 | "@babel/preset-typescript": "^7.18.6", 25 | "@rollup/plugin-babel": "^6.0.3", 26 | "@rollup/plugin-commonjs": "^24.0.0", 27 | "@rollup/plugin-node-resolve": "^15.0.1", 28 | "@rollup/plugin-typescript": "^11.0.0", 29 | "@types/jest": "^29.2.5", 30 | "@types/react": "18.0.26", 31 | "@types/react-dom": "18.0.10", 32 | "@typescript-eslint/parser": "^5.48.0", 33 | "auto": "^10.37.6", 34 | "babel-core": "^7.0.0-bridge.0", 35 | "babel-eslint": "10.1.0", 36 | "babel-jest": "^29.3.1", 37 | "babel-plugin-transform-class-properties": "^6.24.1", 38 | "babel-plugin-transform-react-remove-prop-types": "^0.4.24", 39 | "concurrently": "^4.1.2", 40 | "env-cmd": "^10.1.0", 41 | "eslint": "^7.32.0", 42 | "eslint-plugin-import": "^2.21.2", 43 | "eslint-plugin-jest": "^23.13.2", 44 | "eslint-plugin-prettier": "^3.1.4", 45 | "husky": "^1.1.4", 46 | "jest": "^29.3.1", 47 | "jest-cli": "^29.3.1", 48 | "jest-environment-jsdom": "^29.3.1", 49 | "jest-puppeteer": "^6.2.0", 50 | "lerna": "^6.4.1", 51 | "lint-staged": "^8.1.5", 52 | "minify": "^9.1.0", 53 | "prettier": "^2.0.5", 54 | "prettier-eslint": "^15.0.1", 55 | "prettier-eslint-cli": "^7.1.0", 56 | "puppeteer": "^16.2.0", 57 | "react": "^18.2.0", 58 | "react-dom": "^18.2.0", 59 | "rollup": "^3.9.1", 60 | "rollup-plugin-license": "^3.0.1", 61 | "rollup-plugin-terser": "^7.0.2", 62 | "ts-jest": "^29.0.3", 63 | "typescript": "^4.8.2", 64 | "webpack-cli": "^5.0.1" 65 | }, 66 | "resolutions": { 67 | "@types/react": "18.0.26" 68 | }, 69 | "husky": { 70 | "hooks": { 71 | "pre-commit": "lerna run --concurrency 1 --stream precommit" 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /packages/examples/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [["@babel/preset-env", { 3 | "useBuiltIns": "entry", 4 | "corejs": "3.27", 5 | "debug": true 6 | }], "@babel/preset-react"], 7 | "plugins": ["transform-class-properties"], 8 | "env": { 9 | "test": { 10 | "presets": [ 11 | [ 12 | "@babel/preset-env", 13 | { 14 | "targets": { 15 | "node": "current" 16 | } 17 | } 18 | ], 19 | "@babel/preset-react" 20 | ] 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /packages/examples/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["plugin:react/recommended"] 3 | } 4 | -------------------------------------------------------------------------------- /packages/examples/.gitignore: -------------------------------------------------------------------------------- 1 | bundle.js 2 | bundle.js.map 3 | .env 4 | -------------------------------------------------------------------------------- /packages/examples/Playground.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Select from 'react-select'; 3 | 4 | const widthOptions = [ 5 | { value: 'auto', label: 'auto' }, 6 | { value: '100%', label: '100%' }, 7 | { value: '100px', label: '100px' }, 8 | ]; 9 | 10 | const heightOptions = [ 11 | { value: 'auto', label: 'auto' }, 12 | { value: '100%', label: '100%' }, 13 | { value: '100px', label: '100px' }, 14 | ]; 15 | 16 | const directionOptions = [ 17 | { value: 'ltr', label: 'LTR' }, 18 | { value: 'rtl', label: 'RTL' }, 19 | ]; 20 | 21 | export default class Playground extends React.PureComponent { 22 | state = { 23 | height: '100%', 24 | width: '100%', 25 | direction: 'ltr', 26 | }; 27 | 28 | render() { 29 | const { width, height, direction } = this.props; 30 | 31 | return ( 32 |
33 |
34 | {this.props.children(this.state)} 35 |
36 | {width && ( 37 |
38 | 39 | 57 | this.setState({ 58 | height: option.value, 59 | }) 60 | } 61 | options={heightOptions} 62 | value={heightOptions.find( 63 | (option) => option.value === this.state.height 64 | )} 65 | /> 66 |
67 | )} 68 | {direction && ( 69 |
70 | 71 | 41 | this.setState({ 42 | width: option.value 43 | }) 44 | } 45 | options={widthOptions} 46 | value={widthOptions.find( 47 | option => option.value === this.state.width 48 | )} 49 | /> 50 |
51 | )} 52 | {height && ( 53 |
54 | 55 | 73 | this.setState({ 74 | direction: option.value 75 | }) 76 | } 77 | options={directionOptions} 78 | value={directionOptions.find( 79 | option => option.value === this.state.direction 80 | )} 81 | /> 82 |
83 | )} 84 |
85 | ); 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /packages/website/src/components/SEO.js: -------------------------------------------------------------------------------- 1 | /** 2 | * SEO component that queries for data with 3 | * Gatsby's useStaticQuery React hook 4 | * 5 | * See: https://www.gatsbyjs.org/docs/use-static-query/ 6 | */ 7 | 8 | import React from "react" 9 | import PropTypes from "prop-types" 10 | import Helmet from "react-helmet" 11 | import { useStaticQuery, graphql } from "gatsby" 12 | 13 | function SEO({ description, lang, meta, title }) { 14 | const { site } = useStaticQuery( 15 | graphql` 16 | query { 17 | site { 18 | siteMetadata { 19 | title 20 | description 21 | author 22 | } 23 | } 24 | } 25 | ` 26 | ) 27 | 28 | const metaDescription = description || site.siteMetadata.description 29 | 30 | return ( 31 | 72 | ) 73 | } 74 | 75 | SEO.defaultProps = { 76 | lang: `en`, 77 | meta: [], 78 | description: ``, 79 | } 80 | 81 | SEO.propTypes = { 82 | description: PropTypes.string, 83 | lang: PropTypes.string, 84 | meta: PropTypes.arrayOf(PropTypes.object), 85 | title: PropTypes.string.isRequired, 86 | } 87 | 88 | export default SEO 89 | -------------------------------------------------------------------------------- /packages/website/src/demo.css: -------------------------------------------------------------------------------- 1 | /** 2 | * SimpleBar demo. 3 | * Author: Adrien Grsmto 4 | * 5 | * These styles are not required for SimpleBar 6 | * to function. They are used only for styling the demo. 7 | */ 8 | 9 | /* General page styles 10 | *****************************************************************/ 11 | section:after { 12 | content: ""; 13 | display: table; 14 | clear: both; 15 | } 16 | 17 | section + section { 18 | margin-top: 40px; 19 | } 20 | .box { 21 | background: #666; 22 | color: #fff; 23 | } 24 | .col { 25 | float: left; 26 | width: calc(50% - 20px); 27 | } 28 | .col + .col { 29 | margin-left: 40px; 30 | } 31 | .btn { 32 | display: inline-block; 33 | background: #000; 34 | color: #fff; 35 | padding: 8px 12px; 36 | line-height: 1; 37 | text-decoration: none; 38 | -moz-border-radius: 5px; 39 | -webkit-border-radius: 5px; 40 | -o-border-radius: 5px; 41 | border-radius: 5px; 42 | } 43 | .btn:hover { 44 | background: #666; 45 | color: #fff; 46 | } 47 | .btn:visited { 48 | color: #fff; 49 | } 50 | 51 | /* Scrollable elements 52 | *****************************************************************/ 53 | .demo1, 54 | .demo3 { 55 | margin: 10px 0; 56 | width: 100%; 57 | height: 300px; 58 | } 59 | .demo1 p { 60 | margin: 0; 61 | padding: 10px; 62 | min-width: 230px; 63 | } 64 | .demo1 p.odd:hover { 65 | background: #666; 66 | height: 100px; 67 | } 68 | .demo1 p.odd { 69 | background: #f0f0f0; 70 | } 71 | .demo1.width { 72 | width: 230px; 73 | } 74 | .demo1.height { 75 | height: 200px; 76 | } 77 | #demo1 p { 78 | text-align: right; 79 | padding: 0; 80 | } 81 | .demo1-internal { 82 | width: 50%; 83 | height: 300px; 84 | } 85 | .demo4 { 86 | background: grey; 87 | width: 100%; 88 | margin: 10px 0; 89 | padding: 10px; 90 | white-space: nowrap; 91 | overflow: auto; 92 | } 93 | .demo4 .box { 94 | display: inline-block; 95 | /* margin-right: 10px; */ 96 | width: 100px; 97 | height: 150px; 98 | text-align: center; 99 | line-height: 150px; 100 | font-size: 24px; 101 | } 102 | .demo-raw { 103 | margin: 10px 0; 104 | width: 250px; 105 | height: 300px; 106 | overflow: auto; 107 | } 108 | 109 | .demo3 { 110 | height: auto; 111 | max-height: 300px; 112 | } 113 | 114 | .demo5 { 115 | height: 200px; 116 | height: 60px; 117 | direction: rtl; 118 | } 119 | 120 | .demo-both-axis { 121 | overflow: auto; 122 | width: 200px; 123 | height: 200px; 124 | } 125 | 126 | .demo-both-axis--padding { 127 | background: #2f2f2f; 128 | padding: 40px; 129 | } 130 | 131 | .demo-y-axis { 132 | overflow-y: auto; 133 | overflow-x: hidden; 134 | width: 200px; 135 | height: 200px; 136 | } 137 | 138 | .demo-y-axis.simplebar-dragging .simplebar-scrollbar:before { 139 | background-color: red; 140 | } 141 | 142 | .demo-both-axis .box, 143 | .demo-y-axis .box { 144 | width: 600px; 145 | height: 600px; 146 | } 147 | 148 | .height-100 { 149 | position: absolute; 150 | height: 100%; 151 | width: 100%; 152 | background: red; 153 | } 154 | 155 | .sticky { 156 | position: sticky; 157 | top: 0; 158 | background: red; 159 | margin: 0; 160 | } 161 | 162 | .playground { 163 | display: grid; 164 | grid-template-columns: repeat(2, 1fr); 165 | grid-gap: 10px; 166 | } 167 | 168 | .playground__content { 169 | grid-column-start: span 2; 170 | } 171 | 172 | .demo-flex { 173 | display: flex; 174 | width: 100%; 175 | } 176 | 177 | .demo-flex > div { 178 | height: 300px; 179 | } 180 | 181 | .demo-flex > div .content { 182 | height: 600px; 183 | } 184 | 185 | .demo-flex .left { 186 | width: 200px; 187 | background: #c5e0f7; 188 | } 189 | 190 | .demo-flex .center { 191 | flex: 1; 192 | } 193 | 194 | .demo-flex .right { 195 | width: 200px; 196 | transition: width 0.3s; 197 | background: #ffcfcf; 198 | } 199 | 200 | .demo-height-auto { 201 | width: 25vw; 202 | } 203 | 204 | .demo-height-auto .inner { 205 | margin-bottom: 2em; 206 | width: 25vw; 207 | } 208 | -------------------------------------------------------------------------------- /packages/website/src/html.js: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | import PropTypes from "prop-types" 3 | 4 | const simpleBarFallbackCss = ` 5 | .simplebar-content-wrapper { 6 | overflow: auto; 7 | } 8 | ` 9 | 10 | export default function HTML(props) { 11 | return ( 12 | 13 | 14 | 15 | 16 | 20 | {props.headComponents} 21 | 22 | 23 | {props.preBodyComponents} 24 | 28 |
33 | {props.postBodyComponents} 34 | 35 | 36 | ) 37 | } 38 | 39 | HTML.propTypes = { 40 | htmlAttributes: PropTypes.object, 41 | headComponents: PropTypes.array, 42 | bodyAttributes: PropTypes.object, 43 | preBodyComponents: PropTypes.array, 44 | body: PropTypes.string, 45 | postBodyComponents: PropTypes.array, 46 | } 47 | -------------------------------------------------------------------------------- /packages/website/src/images/browserstack.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Grsmto/simplebar/3885152e72af29662d613dca32f7b76d4120f184/packages/website/src/images/browserstack.png -------------------------------------------------------------------------------- /packages/website/src/images/favicon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /packages/website/src/images/users/storybook.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /packages/website/src/images/users/twitch.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /packages/website/src/images/users/zulip.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /packages/website/src/pages/404.js: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | 3 | import Layout from "../components/Layout" 4 | import SEO from "../components/SEO" 5 | 6 | const NotFoundPage = () => ( 7 | 8 | 9 |

NOT FOUND

10 |

You just hit a route that doesn't exist... the sadness.

11 |
12 | ) 13 | 14 | export default NotFoundPage 15 | -------------------------------------------------------------------------------- /packages/website/src/pages/examples.js: -------------------------------------------------------------------------------- 1 | /** @jsx jsx */ 2 | import { jsx } from "theme-ui" 3 | 4 | import Layout from "../components/Layout" 5 | import SEO from "../components/SEO" 6 | import Demo from "../../../examples/Demo" 7 | 8 | import "../demo.css" 9 | 10 | const ExamplePage = () => { 11 | return ( 12 | 13 | 14 |
20 |

25 | Simplebar examples 26 |

27 | 28 |
29 |
30 | ) 31 | } 32 | 33 | export default ExamplePage 34 | -------------------------------------------------------------------------------- /packages/website/src/pages/index.js: -------------------------------------------------------------------------------- 1 | /** @jsx jsx */ 2 | import { jsx, Styled } from "theme-ui" 3 | import { useEffect, useState } from "react" 4 | import { graphql, withPrefix } from "gatsby" 5 | import SimpleBar from "simplebar-react" 6 | import "simplebar-react/dist/simplebar.min.css" 7 | import { FiGithub } from "react-icons/fi" 8 | import { MdStar } from "react-icons/md" 9 | 10 | import Layout from "../components/Layout" 11 | import SEO from "../components/SEO" 12 | import List from "../components/List" 13 | 14 | import LogoUrl from "../images/logo.svg" 15 | import TwitchUrl from "../images/users/twitch.svg" 16 | import StorybookUrl from "../images/users/storybook.svg" 17 | import ZulipUrl from "../images/users/zulip.svg" 18 | 19 | const verticalCenter = { 20 | display: "inline-flex", 21 | alignItems: "center", 22 | } 23 | 24 | function useGitHubStars() { 25 | const [stars, setStars] = useState(null) 26 | useEffect(() => { 27 | fetch("https://api.github.com/repos/grsmto/simplebar") 28 | .then((result) => result.json()) 29 | .then((response) => setStars(response.stargazers_count)) 30 | }, []) 31 | return stars 32 | } 33 | 34 | const IndexPage = ({ data }) => { 35 | const { 36 | markdownRemark: { html }, 37 | } = data 38 | const stars = useGitHubStars() 39 | 40 | return ( 41 | 42 | 43 |
44 |
45 | SimpleBar logo 52 |
53 |
54 |

63 | Custom scrollbars made simple, lightweight, easy to use and 64 | cross-browser. 65 |

66 | 85 | 86 | 102 | 103 | 104 | 105 |

Who is using it?

106 | 117 |
  • 118 | Twitch 119 |
  • 120 |
  • 121 | Storybook 122 |
  • 123 |
  • 124 | Zulip 125 |
  • 126 |
    127 |
    128 | ) 129 | } 130 | 131 | export default IndexPage 132 | 133 | export const pageQuery = graphql` 134 | { 135 | markdownRemark { 136 | html 137 | } 138 | } 139 | ` 140 | -------------------------------------------------------------------------------- /packages/website/src/theme.js: -------------------------------------------------------------------------------- 1 | import baseTheme from "@theme-ui/preset-base" 2 | 3 | const theme = { 4 | ...baseTheme, 5 | colors: { 6 | body: "#2e2e2e", 7 | background: "#fff", 8 | primary: "#DC8D37", 9 | }, 10 | fonts: { 11 | body: '"Nunito", sans-serif', 12 | }, 13 | fontWeights: { 14 | body: 500, 15 | bold: 700, 16 | heading: 800, 17 | }, 18 | fontSizes: { 19 | 0: "1rem", // 10px 20 | 1: "1.2rem", // 12px 21 | 2: "1.4rem", // 14px 22 | 3: "1.6rem", // 16px 23 | 4: "1.9rem", // 19px 24 | 5: "2.3rem", // 23px 25 | 6: "2.8rem", // 28px 26 | 7: "3.8rem", // 38px 27 | 8: "4.8rem", // 48px 28 | 9: "7rem", // 70px 29 | 10: "9rem", // 90px 30 | }, 31 | styles: { 32 | root: { 33 | h1: { 34 | display: "none", 35 | }, 36 | h3: { 37 | mt: 4, 38 | }, 39 | h4: { 40 | mt: 4, 41 | mb: 0, 42 | fontSize: 4, 43 | }, 44 | "p:first-of-type": { 45 | mt: 0, 46 | }, 47 | }, 48 | }, 49 | } 50 | 51 | theme.fontSizes.body = theme.fontSizes[3] 52 | 53 | export default theme 54 | -------------------------------------------------------------------------------- /rollup.config.mjs: -------------------------------------------------------------------------------- 1 | export const getExternals = (pkg) => (id) => { 2 | if ( 3 | Object.keys(pkg.dependencies).find((dep) => id === dep) || 4 | Object.keys(pkg.peerDependencies || {}).find((dep) => id === dep) || 5 | id.match(/(lodash).+/) || 6 | id.match(/(lodash-es).+/) || 7 | id.match(/(core-js).+/) || 8 | id.match(/(@babel).+/) 9 | ) { 10 | return true; 11 | } 12 | 13 | return false; 14 | }; 15 | 16 | export const getBanner = (pkg) => ({ 17 | banner: ` 18 | ${pkg.name} - v${pkg.version} 19 | ${pkg.description} 20 | ${pkg.homepage} 21 | 22 | Made by ${pkg.author} 23 | Under ${pkg.license} License 24 | `, 25 | }); 26 | 27 | export const babelConfig = { 28 | extensions: ['.js', '.ts'], 29 | exclude: ['**/node_modules/**'], 30 | babelHelpers: 'runtime', 31 | }; 32 | 33 | export const tsConfig = { 34 | outDir: 'dist', 35 | tsconfig: '../../tsconfig.json', 36 | exclude: ['**/*.test.ts', '**/*.test.tsx', 'tests/*'], 37 | }; 38 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": ["**/*.ts", "**/*.tsx", "**/*.js"], 3 | "compilerOptions": { 4 | "strict": true, 5 | "esModuleInterop": true, 6 | "skipLibCheck": true, 7 | "forceConsistentCasingInFileNames": true, 8 | "outDir": "dist", 9 | "declaration": true, 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /web.sketch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Grsmto/simplebar/3885152e72af29662d613dca32f7b76d4120f184/web.sketch --------------------------------------------------------------------------------