├── .gitignore ├── LICENSE ├── MANIFEST.in ├── README.md ├── app.py ├── demo.gif ├── setup.py └── streamlit_custom_slider ├── __init__.py └── frontend ├── .env ├── .gitignore ├── .prettierrc ├── package-lock.json ├── package.json ├── public ├── bootstrap.min.css └── index.html ├── src ├── CustomSlider.tsx ├── index.tsx └── react-app-env.d.ts └── tsconfig.json /.gitignore: -------------------------------------------------------------------------------- 1 | ######################################################################## 2 | # Python - https://github.com/github/gitignore/blob/master/Python.gitignore 3 | ######################################################################## 4 | # Byte-compiled / optimized / DLL files 5 | __pycache__/ 6 | *.py[cod] 7 | *$py.class 8 | 9 | # Distribution / packaging 10 | build/ 11 | dist/ 12 | eggs/ 13 | .eggs/ 14 | *.egg-info/ 15 | *.egg 16 | 17 | # Unit test / coverage reports 18 | .coverage 19 | .coverage\.* 20 | .pytest_cache/ 21 | .mypy_cache/ 22 | test-reports 23 | 24 | # Test fixtures 25 | cffi_bin 26 | 27 | # Pyenv Stuff 28 | .python-version 29 | 30 | ######################################################################## 31 | # OSX - https://github.com/github/gitignore/blob/master/Global/macOS.gitignore 32 | ######################################################################## 33 | .DS_Store 34 | .DocumentRevisions-V100 35 | .fseventsd 36 | .Spotlight-V100 37 | .TemporaryItems 38 | .Trashes 39 | .VolumeIcon.icns 40 | .com.apple.timemachine.donotpresent 41 | 42 | ######################################################################## 43 | # node - https://github.com/github/gitignore/blob/master/Node.gitignore 44 | ######################################################################## 45 | # Logs 46 | npm-debug.log* 47 | yarn-debug.log* 48 | yarn-error.log* 49 | 50 | # Dependency directories 51 | node_modules/ 52 | 53 | # Coverage directory used by tools like istanbul 54 | coverage/ 55 | 56 | # Lockfiles 57 | yarn.lock 58 | package-lock.json 59 | 60 | ######################################################################## 61 | # JetBrains 62 | ######################################################################## 63 | .idea 64 | 65 | ######################################################################## 66 | # VSCode 67 | ######################################################################## 68 | .vscode/ 69 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2018 The Python Packaging Authority 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | recursive-include package/frontend/build * 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Streamlit Custom Slider - Blog post 2 | 3 | Source code for the [Streamlit Components tutorial](https://streamlit-components-tutorial.netlify.app). 4 | 5 |  6 | 7 | Checkout the branch you're interested in 8 | 9 | ``` 10 | git checkout partx 11 | ``` 12 | 13 | Install streamlit and custom library: 14 | 15 | ``` 16 | pip install streamlit 17 | pip install -e . 18 | ``` 19 | 20 | Install npm dependencies : 21 | 22 | ``` 23 | cd streamlit_custom_slider/frontend 24 | npm install 25 | ``` 26 | 27 | Run custom components web server : 28 | 29 | ``` 30 | cd streamlit_custom_slider/frontend 31 | npm run start 32 | ``` 33 | 34 | Run Streamlit code : 35 | 36 | ``` 37 | streamlit run app.py 38 | ``` 39 | -------------------------------------------------------------------------------- /app.py: -------------------------------------------------------------------------------- 1 | import streamlit as st 2 | from streamlit_custom_slider import st_custom_slider 3 | from streamlit_custom_slider import st_range_slider 4 | 5 | v_custom = st_custom_slider('Hello world', 0, 100, 50, key="slider1") 6 | st.write(v_custom) 7 | 8 | # Add a range slider 9 | v_custom_range = st_range_slider('Hello world', 0, 100, (20, 60), key="slider2") 10 | st.write(v_custom_range) -------------------------------------------------------------------------------- /demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andfanilo/streamlit-custom-slider/6e71b3ca6d3c68ab3c26cba61cd3d08c74e02898/demo.gif -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | import setuptools 2 | 3 | setuptools.setup( 4 | name="streamlit-custom-slider", 5 | version="0.1.0", 6 | author="", 7 | author_email="", 8 | description="", 9 | long_description="", 10 | long_description_content_type="text/plain", 11 | url="", 12 | packages=setuptools.find_packages(), 13 | include_package_data=True, 14 | classifiers=[], 15 | python_requires=">=3.6", 16 | install_requires=[ 17 | # By definition, a Custom Component depends on Streamlit. 18 | # If your component has other Python dependencies, list 19 | # them here. 20 | "streamlit >= 0.63", 21 | ], 22 | ) 23 | -------------------------------------------------------------------------------- /streamlit_custom_slider/__init__.py: -------------------------------------------------------------------------------- 1 | import os 2 | import streamlit.components.v1 as components 3 | 4 | from typing import Tuple 5 | 6 | 7 | # Now the React interface only accepts an array of 1 or 2 elements. 8 | _component_func = components.declare_component( 9 | "custom_slider", 10 | url="http://localhost:3001", 11 | ) 12 | 13 | 14 | # Edit arguments sent and result received from React component, so the initial input is converted to an array and returned value extracted from the component 15 | def st_custom_slider(label: str, min_value: int, max_value: int, value: int = 0, key=None) -> int: 16 | component_value = _component_func(label=label, minValue=min_value, maxValue=max_value, initialValue=[value], key=key, default=[value]) 17 | return component_value[0] 18 | 19 | 20 | # Define a new public method which takes as input a tuple of numbers to define a range slider, and returns back a tuple. 21 | def st_range_slider(label: str, min_value: int, max_value: int, value: Tuple[int, int], key=None) -> Tuple[int, int]: 22 | component_value = _component_func(label=label, minValue=min_value, maxValue=max_value, initialValue=value, key=key, default=value) 23 | return tuple(component_value) -------------------------------------------------------------------------------- /streamlit_custom_slider/frontend/.env: -------------------------------------------------------------------------------- 1 | # Run the component's dev server on :3001 2 | # (The Streamlit dev server already runs on :3000) 3 | PORT=3001 4 | 5 | # Don't automatically open the web browser on `npm run start`. 6 | BROWSER=none 7 | -------------------------------------------------------------------------------- /streamlit_custom_slider/frontend/.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 | yarn.lock 8 | 9 | # testing 10 | /coverage 11 | 12 | # production 13 | /build 14 | 15 | # misc 16 | .DS_Store 17 | .env.local 18 | .env.development.local 19 | .env.test.local 20 | .env.production.local 21 | 22 | npm-debug.log* 23 | yarn-debug.log* 24 | yarn-error.log* 25 | -------------------------------------------------------------------------------- /streamlit_custom_slider/frontend/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "endOfLine": "lf", 3 | "semi": false, 4 | "trailingComma": "es5" 5 | } 6 | -------------------------------------------------------------------------------- /streamlit_custom_slider/frontend/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "streamlit_custom_slider", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@testing-library/jest-dom": "^4.2.4", 7 | "@testing-library/react": "^9.3.2", 8 | "@testing-library/user-event": "^7.1.2", 9 | "@types/hoist-non-react-statics": "^3.3.1", 10 | "@types/jest": "^24.0.0", 11 | "@types/node": "^12.0.0", 12 | "@types/react": "^16.9.0", 13 | "@types/react-dom": "^16.9.0", 14 | "@types/styletron-engine-atomic": "^1.1.0", 15 | "@types/styletron-react": "^5.0.2", 16 | "@types/styletron-standard": "^2.0.0", 17 | "apache-arrow": "^0.17.0", 18 | "baseui": "^9.85.0", 19 | "bootstrap": "^4.4.1", 20 | "event-target-shim": "^5.0.1", 21 | "hoist-non-react-statics": "^3.3.2", 22 | "react": "^16.13.1", 23 | "react-dom": "^16.13.1", 24 | "react-scripts": "3.4.1", 25 | "streamlit-component-lib": "^1.1.3", 26 | "styletron-engine-atomic": "^1.4.6", 27 | "styletron-react": "^5.2.7", 28 | "typescript": "~3.7.2" 29 | }, 30 | "scripts": { 31 | "start": "react-scripts start", 32 | "build": "react-scripts build", 33 | "test": "react-scripts test", 34 | "eject": "react-scripts eject" 35 | }, 36 | "eslintConfig": { 37 | "extends": "react-app" 38 | }, 39 | "browserslist": { 40 | "production": [ 41 | ">0.2%", 42 | "not dead", 43 | "not op_mini all" 44 | ], 45 | "development": [ 46 | "last 1 chrome version", 47 | "last 1 firefox version", 48 | "last 1 safari version" 49 | ] 50 | }, 51 | "homepage": "." 52 | } 53 | -------------------------------------------------------------------------------- /streamlit_custom_slider/frontend/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 |