├── .gitignore ├── .pre-commit-config.yaml ├── LICENSE ├── MANIFEST.in ├── README.md ├── friends_graph.png ├── setup.py └── streamlit_react_flow ├── __init__.py └── frontend ├── .prettierrc ├── package-lock.json ├── package.json ├── public ├── bootstrap.min.css └── index.html ├── src ├── DragandDropComponent.tsx ├── ReactFlowComponent.tsx ├── index.tsx ├── react-app-env.d.ts └── sidebar.js └── tsconfig.json /.gitignore: -------------------------------------------------------------------------------- 1 | dask-worker-space/ 2 | 3 | # Byte-compiled / optimized / DLL files 4 | __pycache__/ 5 | *.py[cod] 6 | *$py.class 7 | 8 | # C extensions 9 | *.so 10 | 11 | # Distribution / packaging 12 | .Python 13 | build/ 14 | develop-eggs/ 15 | dist/ 16 | downloads/ 17 | eggs/ 18 | .eggs/ 19 | lib/ 20 | lib64/ 21 | parts/ 22 | sdist/ 23 | var/ 24 | wheels/ 25 | pip-wheel-metadata/ 26 | share/python-wheels/ 27 | *.egg-info/ 28 | .installed.cfg 29 | *.egg 30 | MANIFEST 31 | 32 | # PyInstaller 33 | # Usually these files are written by a python script from a template 34 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 35 | *.manifest 36 | *.spec 37 | 38 | # Installer logs 39 | pip-log.txt 40 | pip-delete-this-directory.txt 41 | 42 | # Unit test / coverage reports 43 | htmlcov/ 44 | .tox/ 45 | .nox/ 46 | .coverage 47 | .coverage.* 48 | .cache 49 | nosetests.xml 50 | coverage.xml 51 | *.cover 52 | *.py,cover 53 | .hypothesis/ 54 | .pytest_cache/ 55 | 56 | # Translations 57 | *.mo 58 | *.pot 59 | 60 | # Django stuff: 61 | *.log 62 | local_settings.py 63 | db.sqlite3 64 | db.sqlite3-journal 65 | 66 | # Flask stuff: 67 | instance/ 68 | .webassets-cache 69 | 70 | # Scrapy stuff: 71 | .scrapy 72 | 73 | # Sphinx documentation 74 | docs/_build/ 75 | 76 | # PyBuilder 77 | target/ 78 | 79 | # Jupyter Notebook 80 | .ipynb_checkpoints 81 | 82 | # IPython 83 | profile_default/ 84 | ipython_config.py 85 | 86 | # pyenv 87 | .python-version 88 | 89 | # pipenv 90 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 91 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 92 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 93 | # install all needed dependencies. 94 | #Pipfile.lock 95 | 96 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 97 | __pypackages__/ 98 | 99 | # Celery stuff 100 | celerybeat-schedule 101 | celerybeat.pid 102 | 103 | # SageMath parsed files 104 | *.sage.py 105 | 106 | # Environments 107 | .env 108 | .venv 109 | env/ 110 | venv/ 111 | ENV/ 112 | env.bak/ 113 | venv.bak/ 114 | 115 | # Spyder project settings 116 | .spyderproject 117 | .spyproject 118 | 119 | # Rope project settings 120 | .ropeproject 121 | 122 | # PyCharm project settings 123 | .idea 124 | 125 | # mkdocs documentation 126 | /site 127 | 128 | # mypy 129 | .mypy_cache/ 130 | .dmypy.json 131 | dmypy.json 132 | 133 | # Pyre type checker 134 | .pyre/ 135 | .DS_Store 136 | junit/ 137 | node_modules/* 138 | **/node_modules 139 | -------------------------------------------------------------------------------- /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | repos: 2 | - repo: https://github.com/psf/black 3 | rev: 19.10b0 4 | hooks: 5 | - id: black 6 | language_version: python3 7 | - repo: https://github.com/pycqa/isort 8 | rev: 5.7.0 9 | hooks: 10 | - id: isort 11 | args: 12 | - "--profile" 13 | - "black" 14 | - repo: https://github.com/pre-commit/pre-commit-hooks 15 | rev: v3.2.0 16 | hooks: 17 | - id: trailing-whitespace 18 | - id: end-of-file-fixer 19 | - id: check-yaml 20 | exclude: ^continuous_integration/recipe/ 21 | - id: check-added-large-files 22 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2018-2021 Streamlit Inc. 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 streamlit_react_flow/frontend/build * 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # streamlit-react-flow 2 | 3 | A streamlit wrapper for easy-to-use flow graph library https://reactflow.dev/ 4 | 5 | ### installation 6 | 7 | ``` 8 | pip install streamlit-react-flow 9 | ``` 10 | 11 | ### example 12 | 13 | ```python 14 | from streamlit_react_flow import react_flow 15 | import streamlit as st 16 | 17 | st.title("React-Flow Test") 18 | 19 | st.subheader("Friends Graph") 20 | 21 | elements = [ 22 | { "id": '1', "data": { "label": 'Guru' }, "type":"input","style": { "background": '#ffcc50', "width": 100 }, 23 | "position": { "x": 100, "y": 100 } }, 24 | { "id": '2', "data": { "label": 'Achyuth' },"position": { "x": 300, "y": 100 }}, 25 | { "id": 'e1-2', "source": '1', "target": '2', "animated": True }, 26 | ] 27 | 28 | elements.extend([{"id":i+3,"data":{"label":name },"type":"output","position": { "x": 170*i, "y": 300+i }} for i,name in enumerate(["Aravind","Manoj","Velmurugan","sridhar"])]) 29 | elements.extend([{"id":f"e{i}-{j}","source":i,"target":j} for i,j in [(1,3),(1,4),(1,5),(1,6)]]) 30 | flowStyles = { "height": 500,"width":1100 } 31 | 32 | # Create an instance of our component with a constant `name` arg, and 33 | # print its output value. 34 | react_flow("friends",elements=elements,flow_styles=flowStyles) 35 | 36 | ``` 37 | 38 | ### The above example produces following graph 39 | 40 | ![](friends_graph.png) 41 | -------------------------------------------------------------------------------- /friends_graph.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rajagurunath/streamlit-react-flow/314d6e42cc50aef74d4aa4be991cca31323c4f48/friends_graph.png -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | import setuptools 2 | 3 | setuptools.setup( 4 | name="streamlit-react-flow", 5 | version="0.0.3", 6 | author="Gurunath", 7 | author_email="gurunathrajagopal@gmail.com", 8 | description="A Wrapper around React-flow component", 9 | long_description="A flow graph component using react-flow and streamlit", 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_react_flow/__init__.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | import streamlit.components.v1 as components 4 | 5 | # Create a _RELEASE constant. We'll set this to False while we're developing 6 | # the component, and True when we're ready to package and distribute it. 7 | # (This is, of course, optional - there are innumerable ways to manage your 8 | # release process.) 9 | _RELEASE = True 10 | 11 | # Declare a Streamlit component. `declare_component` returns a function 12 | # that is used to create instances of the component. We're naming this 13 | # function "_react_flow_func", with an underscore prefix, because we don't want 14 | # to expose it directly to users. Instead, we will create a custom wrapper 15 | # function, below, that will serve as our component's public API. 16 | 17 | # It's worth noting that this call to `declare_component` is the 18 | # *only thing* you need to do to create the binding between Streamlit and 19 | # your component frontend. Everything else we do in this file is simply a 20 | # best practice. 21 | 22 | if not _RELEASE: 23 | _react_flow_func = components.declare_component( 24 | # We give the component a simple, descriptive name ("react_flow" 25 | # does not fit this bill, so please choose something better for your 26 | # own component :) 27 | "react_flow", 28 | # Pass `url` here to tell Streamlit that the component will be served 29 | # by the local dev server that you run via `npm run start`. 30 | # (This is useful while your component is in development.) 31 | url="http://localhost:3001", 32 | ) 33 | else: 34 | # When we're distributing a production version of the component, we'll 35 | # replace the `url` param with `path`, and point it to to the component's 36 | # build directory: 37 | parent_dir = os.path.dirname(os.path.abspath(__file__)) 38 | build_dir = os.path.join(parent_dir, "frontend/build") 39 | _react_flow_func = components.declare_component("react_flow", path=build_dir) 40 | 41 | 42 | # Create a wrapper function for the component. This is an optional 43 | # best practice - we could simply expose the component function returned by 44 | # `declare_component` and call it done. The wrapper allows us to customize 45 | # our component's API: we can pre-process its input args, post-process its 46 | # output value, and add a docstring for users. 47 | def simple_react_flow(name, elements={}, flow_styles={}, with_controls=False, key=None): 48 | """Create a new instance of "React flow graph" using the elements dictionary. 49 | 50 | Parameters 51 | ---------- 52 | name: str 53 | The name of the thing we're saying hello to. The component will display 54 | the text "Hello, {name}!" 55 | elements: dict 56 | nodes and edges 57 | flow_styles: dict 58 | flow properties 59 | key: str or None 60 | An optional key that uniquely identifies this component. If this is 61 | None, and the component's arguments are changed, the component will 62 | be re-mounted in the Streamlit frontend and lose its current state. 63 | 64 | Returns 65 | ------- 66 | None 67 | """ 68 | # Call through to our private component function. Arguments we pass here 69 | # will be sent to the frontend, where they'll be available in an "args" 70 | # dictionary. 71 | # 72 | # "default" is a special argument that specifies the initial return 73 | # value of the component before the user has interacted with it. 74 | component_value = _react_flow_func( 75 | name=name, 76 | elements=elements, 77 | flowStyles=flow_styles, 78 | key=key, 79 | default=0, 80 | withControls=with_controls, 81 | component_name="SimpleReactFlow", 82 | ) 83 | 84 | # We could modify the value returned from the component if we wanted. 85 | # There's no need to do this in our simple example - but it's an option. 86 | return component_value 87 | 88 | 89 | def drag_and_drop_flow(name, elements={}, flow_styles={}, key=None): 90 | """Create a new instance of "Drag and drop component". 91 | 92 | Parameters 93 | ---------- 94 | name: str 95 | The name of the thing we're saying hello to. The component will display 96 | the text "Hello, {name}!" 97 | elements: dict 98 | nodes and edges 99 | flow_styles: dict 100 | flow properties 101 | key: str or None 102 | An optional key that uniquely identifies this component. If this is 103 | None, and the component's arguments are changed, the component will 104 | be re-mounted in the Streamlit frontend and lose its current state. 105 | 106 | Returns 107 | ------- 108 | comming soon 109 | 110 | """ 111 | # Call through to our private component function. Arguments we pass here 112 | # will be sent to the frontend, where they'll be available in an "args" 113 | # dictionary. 114 | # 115 | # "default" is a special argument that specifies the initial return 116 | # value of the component before the user has interacted with it. 117 | component_value = _react_flow_func( 118 | name=name, 119 | elements=elements, 120 | flowStyles=flow_styles, 121 | key=key, 122 | default=0, 123 | component_name="DragandDropComponent", 124 | ) 125 | 126 | # We could modify the value returned from the component if we wanted. 127 | # There's no need to do this in our simple example - but it's an option. 128 | return component_value 129 | 130 | 131 | # Add some test code to play with the component while it's in development. 132 | # During development, we can run this just as we would any other Streamlit 133 | # app: `$ streamlit run react_flow/__init__.py` 134 | if not _RELEASE: 135 | # testing 136 | import streamlit as st 137 | 138 | st.title("React-Flow Test") 139 | 140 | st.subheader("Friends Graph") 141 | 142 | elements = [ 143 | { 144 | "id": "1", 145 | "data": {"label": "Guru"}, 146 | "type": "input", 147 | "style": {"background": "#ffcc50", "width": 100}, 148 | "position": {"x": 100, "y": 100}, 149 | }, 150 | {"id": "2", "data": {"label": "Achyuth"}, "position": {"x": 300, "y": 100}}, 151 | {"id": "e1-2", "source": "1", "target": "2", "animated": True}, 152 | ] 153 | 154 | elements.extend( 155 | [ 156 | { 157 | "id": i + 3, 158 | "data": {"label": name}, 159 | "type": "output", 160 | "position": {"x": 170 * i, "y": 300 + i}, 161 | } 162 | for i, name in enumerate(["Aravind", "Manoj", "Velmurugan", "sridhar"]) 163 | ] 164 | ) 165 | elements.extend( 166 | [ 167 | {"id": f"e{i}-{j}", "source": i, "target": j} 168 | for i, j in [(1, 3), (1, 4), (1, 5), (1, 6)] 169 | ] 170 | ) 171 | flowStyles = {"height": 500, "width": 1100} 172 | 173 | # Create an instance of our component with a constant `name` arg, and 174 | # print its output value. 175 | simple_react_flow( 176 | "friends", elements=elements, flow_styles=flowStyles, with_controls=True 177 | ) 178 | 179 | st.subheader("Dask-sql Plan") 180 | 181 | plan = "LogicalProject(monthh=[CAST(Reinterpret(-(CAST($0):TIMESTAMP(0), CAST($1):TIMESTAMP(0)))):INTEGER], yearr=[CAST(/INT(Reinterpret(-(CAST($0):TIMESTAMP(0), CAST($1):TIMESTAMP(0))), 12)):INTEGER])\n LogicalTableScan(table=[[root, test]])\n" 182 | plan = plan.strip( 183 | "\n" 184 | ) # 'LogicalProject(ms=[*(CAST(/INT(Reinterpret(-(CAST($0):TIMESTAMP(0), CAST($1):TIMESTAMP(0))), 1000)):INTEGER, 1000000)], sec=[CAST(/INT(Reinterpret(-(CAST($0):TIMESTAMP(0), CAST($1):TIMESTAMP(0))), 1000)):INTEGER], minn=[CAST(/INT(Reinterpret(-(CAST($0):TIMESTAMP(0), CAST($1):TIMESTAMP(0))), 60000)):INTEGER], hr=[CAST(/INT(Reinterpret(-(CAST($0):TIMESTAMP(0), CAST($1):TIMESTAMP(0))), 3600000)):INTEGER], dayy=[CAST(/INT(Reinterpret(-(CAST($0):TIMESTAMP(0), CAST($1):TIMESTAMP(0))), 86400000)):INTEGER])\n LogicalTableScan(table=[[root, test]])' 185 | subplans = plan.split("\n")[::-1] 186 | plan_elements = [ 187 | { 188 | "id": f"{i}", 189 | "data": {"label": text}, 190 | "style": {"background": "#62c1f0", "width": 300,}, 191 | "position": {"x": 100, "y": 100 + i * 100}, 192 | } 193 | for i, text in enumerate(subplans) 194 | ] 195 | plan_edges = [ 196 | {"id": f"conn{i}_{1+1}", "source": i, "target": i + 1} 197 | for i in range(len(subplans) - 1) 198 | ] 199 | plan_elements.extend(plan_edges) 200 | simple_react_flow("dask-sql", elements=plan_elements, flow_styles=flowStyles) 201 | 202 | drag_and_drop_flow("dask-sql", elements=plan_elements, flow_styles=flowStyles) 203 | -------------------------------------------------------------------------------- /streamlit_react_flow/frontend/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "endOfLine": "lf", 3 | "semi": false, 4 | "trailingComma": "es5" 5 | } 6 | -------------------------------------------------------------------------------- /streamlit_react_flow/frontend/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "streamlit_react_flow", 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/jest": "^24.0.0", 10 | "@types/node": "^12.0.0", 11 | "@types/react": "^16.9.0", 12 | "@types/react-dom": "^16.9.0", 13 | "react": "^16.13.1", 14 | "react-dom": "^16.13.1", 15 | "react-flow-renderer": "^9.6.11", 16 | "react-scripts": "3.4.1", 17 | "streamlit-component-lib": "^1.3.0", 18 | "typescript": "^3.7.7" 19 | }, 20 | "scripts": { 21 | "start": "react-scripts start", 22 | "build": "react-scripts build", 23 | "test": "react-scripts test", 24 | "eject": "react-scripts eject" 25 | }, 26 | "eslintConfig": { 27 | "extends": "react-app" 28 | }, 29 | "browserslist": { 30 | "production": [ 31 | ">0.2%", 32 | "not dead", 33 | "not op_mini all" 34 | ], 35 | "development": [ 36 | "last 1 chrome version", 37 | "last 1 firefox version", 38 | "last 1 safari version" 39 | ] 40 | }, 41 | "homepage": "." 42 | } 43 | -------------------------------------------------------------------------------- /streamlit_react_flow/frontend/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Streamlit Component 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /streamlit_react_flow/frontend/src/DragandDropComponent.tsx: -------------------------------------------------------------------------------- 1 | import { 2 | Streamlit, 3 | StreamlitComponentBase, 4 | withStreamlitConnection, 5 | } from "streamlit-component-lib" 6 | import React, { ReactNode,useState } from "react"; 7 | import ReactFlow,{Controls,updateEdge,addEdge} from "react-flow-renderer" 8 | import SideBar from './sidebar' 9 | 10 | interface State { 11 | numClicks: number 12 | isFocused: boolean 13 | } 14 | 15 | /** 16 | * This is a React-based component template. The `render()` function is called 17 | * automatically when your component should be re-rendered. 18 | */ 19 | class DragandDropComponent extends StreamlitComponentBase { 20 | public state = { numClicks: 0, isFocused: false } 21 | 22 | public render = (): ReactNode => { 23 | // Arguments that are passed to the plugin in Python are accessible 24 | // via `this.props.args`. Here, we access the "name" arg. 25 | const name = this.props.args["name"] 26 | const elements = this.props.args['elements'] 27 | const flowStyles = this.props.args['flowStyles'] 28 | // Streamlit sends us a theme object via props that we can use to ensure 29 | // that our component has visuals that match the active theme in a 30 | // streamlit app. 31 | const { theme } = this.props 32 | const style: React.CSSProperties = {} 33 | 34 | // Maintain compatibility with older versions of Streamlit that don't send 35 | // a theme object. 36 | if (theme) { 37 | // Use the theme object to style our button border. Alternatively, the 38 | // theme style is defined in CSS vars. 39 | const borderStyling = `1px solid ${ 40 | this.state.isFocused ? theme.primaryColor : "gray" 41 | }` 42 | style.border = borderStyling 43 | style.outline = borderStyling 44 | } 45 | 46 | return ( 47 |
48 | 50 | 51 |
52 | )}; 53 | } 54 | 55 | // "withStreamlitConnection" is a wrapper function. It bootstraps the 56 | // connection between your component and the Streamlit app, and handles 57 | // passing arguments from Python -> Component. 58 | // 59 | // You don't need to edit withStreamlitConnection (but you're welcome to!). 60 | export default withStreamlitConnection(DragandDropComponent) 61 | -------------------------------------------------------------------------------- /streamlit_react_flow/frontend/src/ReactFlowComponent.tsx: -------------------------------------------------------------------------------- 1 | import { 2 | Streamlit, 3 | StreamlitComponentBase, 4 | withStreamlitConnection, 5 | } from "streamlit-component-lib" 6 | import React, { ReactNode,useState } from "react"; 7 | import ReactFlow,{Controls,updateEdge,addEdge} from "react-flow-renderer" 8 | import SideBar from "./sidebar" 9 | import DragandDropComponent from "./DragandDropComponent" 10 | 11 | 12 | interface State { 13 | numClicks: number 14 | isFocused: boolean 15 | } 16 | 17 | /** 18 | * This is a React-based component template. The `render()` function is called 19 | * automatically when your component should be re-rendered. 20 | */ 21 | class ReactFlowComponent extends StreamlitComponentBase { 22 | public state = { numClicks: 0, isFocused: false } 23 | 24 | public render = (): ReactNode => { 25 | // Arguments that are passed to the plugin in Python are accessible 26 | // via `this.props.args`. Here, we access the "name" arg. 27 | const name = this.props.args["name"] 28 | const elements = this.props.args['elements'] 29 | const flowStyles = this.props.args['flowStyles'] 30 | const componentName = this.props.args['component_name'] 31 | const withControls = this.props.args['withControls'] 32 | // Streamlit sends us a theme object via props that we can use to ensure 33 | // that our component has visuals that match the active theme in a 34 | // streamlit app. 35 | const { theme } = this.props 36 | const style: React.CSSProperties = {} 37 | 38 | // Maintain compatibility with older versions of Streamlit that don't send 39 | // a theme object. 40 | if (theme) { 41 | // Use the theme object to style our button border. Alternatively, the 42 | // theme style is defined in CSS vars. 43 | const borderStyling = `1px solid ${ 44 | this.state.isFocused ? theme.primaryColor : "gray" 45 | }` 46 | style.border = borderStyling 47 | style.outline = borderStyling 48 | } 49 | 50 | if (componentName == "SimpleReactFlow"){ 51 | if (withControls ==true){ 52 | return ( 53 | ) 55 | 56 | } 57 | else{ 58 | return ( 59 | ) 61 | } 62 | 63 | } 64 | // TODO: complete the Drag and drop component 65 | else{ 66 | return
67 | 68 |
69 | } 70 | }; 71 | } 72 | 73 | // "withStreamlitConnection" is a wrapper function. It bootstraps the 74 | // connection between your component and the Streamlit app, and handles 75 | // passing arguments from Python -> Component. 76 | // 77 | // You don't need to edit withStreamlitConnection (but you're welcome to!). 78 | export default withStreamlitConnection(ReactFlowComponent) 79 | -------------------------------------------------------------------------------- /streamlit_react_flow/frontend/src/index.tsx: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | import ReactDOM from "react-dom" 3 | import ReactFlowComponent from "./ReactFlowComponent" 4 | import DragandDropComponent from "./DragandDropComponent" 5 | 6 | ReactDOM.render( 7 | 8 | 9 | , 10 | document.getElementById("root") 11 | ) 12 | -------------------------------------------------------------------------------- /streamlit_react_flow/frontend/src/react-app-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /streamlit_react_flow/frontend/src/sidebar.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | export default () => { 4 | const onDragStart = (event, nodeType) => { 5 | event.dataTransfer.setData('application/reactflow', nodeType); 6 | event.dataTransfer.effectAllowed = 'move'; 7 | }; 8 | 9 | return ( 10 | 22 | ); 23 | }; 24 | -------------------------------------------------------------------------------- /streamlit_react_flow/frontend/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "lib": ["dom", "dom.iterable", "esnext"], 5 | "allowJs": true, 6 | "skipLibCheck": true, 7 | "esModuleInterop": true, 8 | "allowSyntheticDefaultImports": true, 9 | "strict": true, 10 | "forceConsistentCasingInFileNames": true, 11 | "module": "esnext", 12 | "moduleResolution": "node", 13 | "resolveJsonModule": true, 14 | "isolatedModules": true, 15 | "noEmit": true, 16 | "jsx": "react" 17 | }, 18 | "include": ["src"] 19 | } 20 | --------------------------------------------------------------------------------