├── LICENSE
├── tests
├── __init__.py
├── requirements.txt
└── test_usage.py
├── .idea
├── .name
├── inspectionProfiles
│ └── Project_Default.xml
├── modules.xml
├── dash-draggable.iml
└── misc.xml
├── .eslintignore
├── .babelrc
├── images
├── animated-1.gif
└── PrettyHandleExample.gif
├── dash_draggable
├── _imports_.py
├── __init__.py
├── package.json
├── dash_draggable.py
├── metadata.json
└── dash_draggable.min.js
├── .prettierrc
├── requirements.txt
├── src
├── demo
│ ├── index.js
│ └── App.js
└── lib
│ ├── index.js
│ └── components
│ └── dash_draggable.react.js
├── MANIFEST.in
├── index.html
├── CONTRIBUTING.md
├── webpack.serve.config.js
├── .npmignore
├── setup.py
├── _validate_init.py
├── package.json
├── webpack.config.js
├── extract-meta.js
├── review_checklist.md
├── .eslintrc
├── usage.py
├── README.md
├── usage_prettyhandle.py
├── .gitignore
└── .pylintrc
/LICENSE:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.idea/.name:
--------------------------------------------------------------------------------
1 | dash-draggable
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | *.css
2 | registerServiceWorker.js
--------------------------------------------------------------------------------
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["env", "react"]
3 | }
4 |
--------------------------------------------------------------------------------
/images/animated-1.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xhluca/dash-draggable/HEAD/images/animated-1.gif
--------------------------------------------------------------------------------
/images/PrettyHandleExample.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xhluca/dash-draggable/HEAD/images/PrettyHandleExample.gif
--------------------------------------------------------------------------------
/dash_draggable/_imports_.py:
--------------------------------------------------------------------------------
1 | from .dash_draggable import dash_draggable
2 |
3 | __all__ = [
4 | "dash_draggable"
5 | ]
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "tabWidth": 4,
3 | "singleQuote": true,
4 | "bracketSpacing": false,
5 | "trailingComma": "es5"
6 | }
7 |
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | # dash is required to call `build:py`
2 | dash
3 | dash-html-components
4 | dash-core-components
5 | sd-material-ui
6 | dash-daq
7 |
--------------------------------------------------------------------------------
/src/demo/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import App from './App';
4 |
5 | ReactDOM.render(, document.getElementById('root'));
6 |
--------------------------------------------------------------------------------
/src/lib/index.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable import/prefer-default-export */
2 | import dash_draggable from './components/dash_draggable.react';
3 |
4 | export {
5 | dash_draggable
6 | };
7 |
--------------------------------------------------------------------------------
/MANIFEST.in:
--------------------------------------------------------------------------------
1 | include dash_draggable/dash_draggable.min.js
2 | include dash_draggable/dash_draggable.dev.js
3 | include dash_draggable/metadata.json
4 | include dash_draggable/package.json
5 | include README.md
6 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | my-dash-component
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # CONTRIBUTING
2 |
3 | This project was generated by the [dash-component-boilerplate](https://github.com/plotly/dash-component-boilerplate) it contains the minimal set of code required to create your own custom Dash component.
4 |
5 |
--------------------------------------------------------------------------------
/.idea/inspectionProfiles/Project_Default.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/tests/requirements.txt:
--------------------------------------------------------------------------------
1 | # Packages needed to run the tests.
2 | # Switch into a virtual environment
3 | # pip install -r requirements.txt
4 |
5 | chromedriver-binary
6 | dash
7 | dash-core-components
8 | dash-html-components
9 | dash-renderer
10 | ipdb
11 | percy
12 | selenium
13 | flake8
14 | pylint
15 | pytest-dash
16 |
--------------------------------------------------------------------------------
/webpack.serve.config.js:
--------------------------------------------------------------------------------
1 | const config = require('./webpack.config.js');
2 |
3 | config.entry = {main: './src/demo/index.js'};
4 | config.output = {filename: 'output.js'};
5 | config.mode = 'development';
6 | config.externals = undefined; // eslint-disable-line
7 | config.devtool = 'inline-source-map';
8 | module.exports = config;
9 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | # dependencies
2 | /node_modules
3 |
4 | # testing
5 | /coverage
6 |
7 | # misc
8 | .DS_Store
9 | .env.local
10 | .env.development.local
11 | .env.test.local
12 | .env.production.local
13 |
14 | npm-debug.log*
15 | yarn-debug.log*
16 | yarn-error.log*
17 |
18 | # Development folders and files
19 | public
20 | src
21 | scripts
22 | config
23 | .travis.yml
24 | CHANGELOG.md
25 | README.md
26 |
--------------------------------------------------------------------------------
/tests/test_usage.py:
--------------------------------------------------------------------------------
1 | # Basic test for the component rendering.
2 | def test_render_component(dash_app, selenium):
3 | # Start a dash app contained in `usage.py`
4 | # dash_app is a fixture by pytest-dash
5 | # It will load a py file containing a Dash instance named `app`
6 | # and start it in a thread.
7 | app = dash_app('usage.py')
8 |
9 | # Get the generated component with selenium
10 | my_component = selenium.find_element_by_id('input')
11 |
--------------------------------------------------------------------------------
/.idea/dash-draggable.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/setup.py:
--------------------------------------------------------------------------------
1 | import json
2 | import os
3 | from setuptools import setup
4 |
5 |
6 | with open(os.path.join('dash_draggable', 'package.json')) as f:
7 | package = json.load(f)
8 |
9 | package_name = package["name"].replace(" ", "_").replace("-", "_")
10 |
11 | setup(
12 | name=package_name,
13 | version=package["version"],
14 | author=package['author'],
15 | packages=[package_name],
16 | include_package_data=True,
17 | license=package['license'],
18 | description=package['description'] if 'description' in package else package_name,
19 | install_requires=[]
20 | )
21 |
--------------------------------------------------------------------------------
/src/demo/App.js:
--------------------------------------------------------------------------------
1 | /* eslint no-magic-numbers: 0 */
2 | import React, {Component} from 'react';
3 | import dash_draggable from '../lib';
4 |
5 | class App extends Component {
6 |
7 | constructor(props) {
8 | super(props);
9 | this.state = {
10 | };
11 | this.setProps = this.setProps.bind(this);
12 | }
13 |
14 | setProps(newProps) {
15 | console.log("You will see this message if props are set correctly");
16 | console.log(newProps);
17 | this.setState(newProps);
18 | }
19 |
20 | render() {
21 | return (
22 |
23 |
28 |
29 | )
30 | }
31 | }
32 |
33 | export default App;
34 |
--------------------------------------------------------------------------------
/dash_draggable/__init__.py:
--------------------------------------------------------------------------------
1 | from __future__ import print_function as _
2 |
3 | import os as _os
4 | import sys as _sys
5 | import json
6 |
7 | import dash as _dash
8 |
9 | # noinspection PyUnresolvedReferences
10 | from ._imports_ import *
11 | from ._imports_ import __all__
12 |
13 | if not hasattr(_dash, 'development'):
14 | print('Dash was not successfully imported. '
15 | 'Make sure you don\'t have a file '
16 | 'named \n"dash.py" in your current directory.', file=_sys.stderr)
17 | _sys.exit(1)
18 |
19 | _basepath = _os.path.dirname(__file__)
20 | _filepath = _os.path.abspath(_os.path.join(_basepath, 'package.json'))
21 | with open(_filepath) as f:
22 | package = json.load(f)
23 |
24 | package_name = package['name'].replace(' ', '_').replace('-', '_')
25 | __version__ = package['version']
26 |
27 | _current_path = _os.path.dirname(_os.path.abspath(__file__))
28 |
29 | _this_module = _sys.modules[__name__]
30 |
31 |
32 | _js_dist = [
33 | {
34 | 'relative_package_path': 'dash_draggable.min.js',
35 | 'dev_package_path': 'dash_draggable.dev.js',
36 | 'external_url': 'https://unpkg.com/{0}@{1}/{0}/{0}.min.js'.format(
37 | __name__, __version__),
38 | 'namespace': package_name
39 | }
40 | ]
41 |
42 | _css_dist = []
43 |
44 |
45 | for _component in __all__:
46 | setattr(locals()[_component], '_js_dist', _js_dist)
47 | setattr(locals()[_component], '_css_dist', _css_dist)
48 |
--------------------------------------------------------------------------------
/_validate_init.py:
--------------------------------------------------------------------------------
1 | """
2 | DO NOT MODIFY
3 | This file is used to validate your publish settings.
4 | """
5 | from __future__ import print_function
6 |
7 | import os
8 | import sys
9 | import importlib
10 |
11 |
12 | components_package = 'dash_draggable'
13 |
14 | components_lib = importlib.import_module(components_package)
15 |
16 | missing_dist_msg = 'Warning {} was not found in `{}.__init__.{}`!!!'
17 | missing_manifest_msg = '''
18 | Warning {} was not found in `MANIFEST.in`!
19 | It will not be included in the build!
20 | '''
21 |
22 | with open('MANIFEST.in', 'r') as f:
23 | manifest = f.read()
24 |
25 |
26 | def check_dist(dist, filename):
27 | # Support the dev bundle.
28 | if filename.endswith('dev.js'):
29 | return True
30 |
31 | return any(
32 | filename in x
33 | for d in dist
34 | for x in (
35 | [d.get('relative_package_path')]
36 | if not isinstance(d.get('relative_package_path'), list)
37 | else d.get('relative_package_path')
38 | )
39 | )
40 |
41 |
42 | def check_manifest(filename):
43 | return filename in manifest
44 |
45 |
46 | def check_file(dist, filename):
47 | if not check_dist(dist, filename):
48 | print(
49 | missing_dist_msg.format(filename, components_package, '_js_dist'),
50 | file=sys.stderr
51 | )
52 | if not check_manifest(filename):
53 | print(missing_manifest_msg.format(filename),
54 | file=sys.stderr)
55 |
56 |
57 | for cur, _, files in os.walk(components_package):
58 | for f in files:
59 |
60 | if f.endswith('js'):
61 | # noinspection PyProtectedMember
62 | check_file(components_lib._js_dist, f)
63 | elif f.endswith('css'):
64 | # noinspection PyProtectedMember
65 | check_file(components_lib._css_dist, f)
66 | elif not f.endswith('py'):
67 | check_manifest(f)
68 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "dash_draggable",
3 | "version": "0.0.1",
4 | "description": "Draggable in Dash",
5 | "main": "build/index.js",
6 | "scripts": {
7 | "start": "webpack-serve ./webpack.serve.config.js --open",
8 | "validate-init": "python _validate_init.py",
9 | "prepublish": "npm run validate-init",
10 | "build:js-dev": "webpack --mode development",
11 | "build:js": "webpack --mode production",
12 | "build:py": "node ./extract-meta.js src/lib/components > dash_draggable/metadata.json && copyfiles package.json dash_draggable && python -c \"import dash; dash.development.component_loader.generate_classes('dash_draggable', 'dash_draggable/metadata.json')\"",
13 | "build:all": "npm run build:js & npm run build:js-dev & npm run build:py"
14 | },
15 | "author": "Xing Han Lu xinghan@plot.ly",
16 | "license": "MIT",
17 | "dependencies": {
18 | "ramda": "^0.25.0",
19 | "react": "15.4.2",
20 | "react-dom": "15.4.2",
21 | "react-draggable": "^3.0.5"
22 | },
23 | "devDependencies": {
24 | "babel-core": "^6.26.3",
25 | "babel-eslint": "^8.2.3",
26 | "babel-loader": "^7.1.4",
27 | "babel-preset-env": "^1.7.0",
28 | "babel-preset-react": "^6.24.1",
29 | "copyfiles": "^2.0.0",
30 | "css-loader": "^0.28.11",
31 | "eslint": "^4.19.1",
32 | "eslint-config-prettier": "^2.9.0",
33 | "eslint-plugin-import": "^2.12.0",
34 | "eslint-plugin-react": "^7.9.1",
35 | "npm": "^6.1.0",
36 | "react-docgen": "^2.20.1",
37 | "style-loader": "^0.21.0",
38 | "webpack": "^4.20.2",
39 | "webpack-cli": "^3.1.1",
40 | "webpack-serve": "^1.0.2"
41 | },
42 | "peerDependencies": {
43 | "react": ">=0.14",
44 | "react-dom": ">=0.14"
45 | },
46 | "engines": {
47 | "node": ">=8.11.0",
48 | "npm": ">=6.1.0"
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | const path = require('path');
2 | const packagejson = require('./package.json');
3 |
4 | const dashLibraryName = packagejson.name.replace(/-/g, '_');
5 |
6 | module.exports = (env, argv) => {
7 |
8 | let mode;
9 |
10 |
11 | // if user specified mode flag take that value
12 | if (argv && argv.mode) {
13 | mode = argv.mode;
14 | }
15 |
16 | // else if configuration object is already set (module.exports) use that value
17 | else if (module.exports && module.exports.mode) {
18 | mode = module.exports = mode;
19 | }
20 |
21 | // else take webpack default
22 | else {
23 | mode = 'production'; // webpack default
24 | }
25 |
26 | return {
27 | entry: {main: './src/lib/index.js'},
28 | output: {
29 | path: path.resolve(__dirname, dashLibraryName),
30 | filename: `${dashLibraryName}.${mode === 'development' ? 'dev' : 'min'}.js`,
31 | library: dashLibraryName,
32 | libraryTarget: 'window',
33 | },
34 | externals: {
35 | react: 'React',
36 | 'react-dom': 'ReactDOM',
37 | 'plotly.js': 'Plotly',
38 | },
39 | module: {
40 | rules: [
41 | {
42 | test: /\.js$/,
43 | exclude: /node_modules/,
44 | use: {
45 | loader: 'babel-loader',
46 | },
47 | },
48 | {
49 | test: /\.css$/,
50 | use: [
51 | {
52 | loader: 'style-loader',
53 | },
54 | {
55 | loader: 'css-loader',
56 | },
57 | ],
58 | },
59 | ],
60 | },
61 | devtool: mode === 'development' ? "eval-source-map" : 'none'
62 | }
63 | };
64 |
--------------------------------------------------------------------------------
/dash_draggable/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "dash_draggable",
3 | "version": "0.0.1",
4 | "description": "Draggable in Dash",
5 | "main": "build/index.js",
6 | "scripts": {
7 | "start": "webpack-serve ./webpack.serve.config.js --open",
8 | "validate-init": "python _validate_init.py",
9 | "prepublish": "npm run validate-init",
10 | "build:js-dev": "webpack --mode development",
11 | "build:js": "webpack --mode production",
12 | "build:py": "node ./extract-meta.js src/lib/components > dash_draggable/metadata.json && copyfiles package.json dash_draggable && python -c \"import dash; dash.development.component_loader.generate_classes('dash_draggable', 'dash_draggable/metadata.json')\"",
13 | "build:all": "npm run build:js & npm run build:js-dev & npm run build:py"
14 | },
15 | "author": "Xing Han Lu xinghan@plot.ly",
16 | "license": "MIT",
17 | "dependencies": {
18 | "acorn": "^6.1.0",
19 | "ramda": "^0.25.0",
20 | "react": "15.4.2",
21 | "react-dom": "15.4.2",
22 | "react-draggable": "^3.0.5"
23 | },
24 | "devDependencies": {
25 | "babel-core": "^6.26.3",
26 | "babel-eslint": "^8.2.3",
27 | "babel-loader": "^7.1.4",
28 | "babel-preset-env": "^1.7.0",
29 | "babel-preset-react": "^6.24.1",
30 | "copyfiles": "^2.0.0",
31 | "css-loader": "^0.28.11",
32 | "eslint": "^4.19.1",
33 | "eslint-config-prettier": "^2.9.0",
34 | "eslint-plugin-import": "^2.12.0",
35 | "eslint-plugin-react": "^7.9.1",
36 | "npm": "^6.1.0",
37 | "react-docgen": "^2.20.1",
38 | "style-loader": "^0.21.0",
39 | "webpack": "^4.20.2",
40 | "webpack-cli": "^3.1.1",
41 | "webpack-serve": "^1.0.2"
42 | },
43 | "peerDependencies": {
44 | "react": ">=0.14",
45 | "react-dom": ">=0.14"
46 | },
47 | "engines": {
48 | "node": ">=8.11.0",
49 | "npm": ">=6.1.0"
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/dash_draggable/dash_draggable.py:
--------------------------------------------------------------------------------
1 | # AUTO GENERATED FILE - DO NOT EDIT
2 |
3 | from dash.development.base_component import Component, _explicitize_args
4 |
5 |
6 | class dash_draggable(Component):
7 | """A dash_draggable component.
8 | ...
9 |
10 | Keyword arguments:
11 | - children (a list of or a singular dash component, string or number; optional): ...
12 | - id (string; optional): The ID used to identify this component in Dash callbacks
13 | - axis (string; optional): ...
14 | - handle (string; optional): ...
15 | - defaultPosition (dict; optional): ...
16 | - position (dict; optional): ...
17 | - grid (list; optional): ...
18 | - lastX (number; optional): ...
19 | - lastY (number; optional): ...
20 | - deltaX (number; optional): ...
21 | - deltaY (number; optional): ...
22 | - moved (boolean; optional): ...
23 | - disabled (boolean; optional): ..."""
24 | @_explicitize_args
25 | def __init__(self, children=None, id=Component.UNDEFINED, onStop=Component.UNDEFINED, axis=Component.UNDEFINED, handle=Component.UNDEFINED, defaultPosition=Component.UNDEFINED, position=Component.UNDEFINED, grid=Component.UNDEFINED, lastX=Component.UNDEFINED, lastY=Component.UNDEFINED, deltaX=Component.UNDEFINED, deltaY=Component.UNDEFINED, moved=Component.UNDEFINED, disabled=Component.UNDEFINED, **kwargs):
26 | self._prop_names = ['children', 'id', 'axis', 'handle', 'defaultPosition', 'position', 'grid', 'lastX', 'lastY', 'deltaX', 'deltaY', 'moved', 'disabled']
27 | self._type = 'dash_draggable'
28 | self._namespace = 'dash_draggable'
29 | self._valid_wildcard_attributes = []
30 | self.available_properties = ['children', 'id', 'axis', 'handle', 'defaultPosition', 'position', 'grid', 'lastX', 'lastY', 'deltaX', 'deltaY', 'moved', 'disabled']
31 | self.available_wildcard_properties = []
32 |
33 | _explicit_args = kwargs.pop('_explicit_args')
34 | _locals = locals()
35 | _locals.update(kwargs) # For wildcard attrs
36 | args = {k: _locals[k] for k in _explicit_args if k != 'children'}
37 |
38 | for k in []:
39 | if k not in args:
40 | raise TypeError(
41 | 'Required argument `' + k + '` was not specified.')
42 | super(dash_draggable, self).__init__(children=children, **args)
43 |
--------------------------------------------------------------------------------
/extract-meta.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | const fs = require('fs');
4 | const path = require('path');
5 | const reactDocs = require('react-docgen');
6 |
7 | const componentPaths = process.argv.slice(2);
8 | if (!componentPaths.length) {
9 | help();
10 | process.exit(1);
11 | }
12 |
13 | const metadata = Object.create(null);
14 | componentPaths.forEach(componentPath =>
15 | collectMetadataRecursively(componentPath)
16 | );
17 | writeOut(metadata);
18 |
19 | function help() {
20 | console.error('usage: ');
21 | console.error(
22 | 'extract-meta path/to/component(s) ' +
23 | ' [path/to/more/component(s), ...] > metadata.json'
24 | );
25 | }
26 |
27 | function writeError(msg, filePath) {
28 | if (filePath) {
29 | process.stderr.write(`Error with path ${filePath}`);
30 | }
31 |
32 | process.stderr.write(msg + '\n');
33 | if (msg instanceof Error) {
34 | process.stderr.write(msg.stack + '\n');
35 | }
36 | }
37 |
38 | function checkWarn(name, value) {
39 | if (value.length < 1) {
40 | process.stderr.write(`\nDescription for ${name} is missing!\n`)
41 | }
42 | }
43 |
44 | function docstringWarning(doc) {
45 | checkWarn(doc.displayName, doc.description);
46 |
47 | Object.entries(doc.props).forEach(
48 | ([name, p]) => checkWarn(`${doc.displayName}.${name}`, p.description)
49 | );
50 | }
51 |
52 |
53 | function parseFile(filepath) {
54 | const urlpath = filepath.split(path.sep).join('/');
55 | let src;
56 |
57 | if (!['.jsx', '.js'].includes(path.extname(filepath))) {
58 | return;
59 | }
60 |
61 | try {
62 | src = fs.readFileSync(filepath);
63 | const doc = metadata[urlpath] = reactDocs.parse(src);
64 | docstringWarning(doc);
65 | } catch (error) {
66 | writeError(error, filepath);
67 | }
68 | }
69 |
70 | function collectMetadataRecursively(componentPath) {
71 | if (fs.lstatSync(componentPath).isDirectory()) {
72 | let dirs;
73 | try {
74 | dirs = fs.readdirSync(componentPath);
75 | } catch (error) {
76 | writeError(error, componentPath);
77 | }
78 | dirs.forEach(filename => {
79 | const filepath = path.join(componentPath, filename);
80 | if (fs.lstatSync(filepath).isDirectory()) {
81 | collectMetadataRecursively(filepath);
82 | } else {
83 | parseFile(filepath);
84 | }
85 | });
86 | } else {
87 | parseFile(componentPath);
88 | }
89 | }
90 |
91 | function writeOut(result) {
92 | console.log(JSON.stringify(result, '\t', 2));
93 | }
94 |
--------------------------------------------------------------------------------
/review_checklist.md:
--------------------------------------------------------------------------------
1 | # Code Review Checklist
2 |
3 | ## Code quality & design
4 |
5 | - Is your code clear? If you had to go back to it in a month, would you be happy to? If someone else had to contribute to it, would they be able to?
6 |
7 | A few suggestions:
8 |
9 | - Make your variable names descriptive and use the same naming conventions throughout the code.
10 |
11 | - For more complex pieces of logic, consider putting a comment, and maybe an example.
12 |
13 | - In the comments, focus on describing _why_ the code does what it does, rather than describing _what_ it does. The reader can most likely read the code, but not necessarily understand why it was necessary.
14 |
15 | - Don't overdo it in the comments. The code should be clear enough to speak for itself. Stale comments that no longer reflect the intent of the code can hurt code comprehension.
16 |
17 | * Don't repeat yourself. Any time you see that the same piece of logic can be applied in multiple places, factor it out into a function, or variable, and reuse that code.
18 | * Scan your code for expensive operations (large computations, DOM queries, React re-renders). Have you done your possible to limit their impact? If not, it is going to slow your app down.
19 |
20 | ## Component API
21 |
22 | - Have you tested your component on the Python side by creating an app in `usage.py` ?
23 |
24 | Do all of your component's props work when set from the back-end?
25 |
26 | Should all of them be settable from the back-end or are some only relevant to user interactions in the front-end?
27 |
28 | - Have you provided some basic documentation about your component? The Dash community uses [react docstrings](https://github.com/plotly/dash-docs/blob/master/tutorial/plugins.py#L45) to provide basic information about dash components. Take a look at this [Checklist component example](https://github.com/plotly/dash-core-components/blob/master/src/components/Checklist.react.js) and others from the dash-core-components repository.
29 |
30 | At a minimum, you should describe what your component does, and describe its props and the features they enable.
31 |
32 | Be careful to use the correct formatting for your docstrings for them to be properly recognized.
33 |
34 | ## Tests
35 |
36 | - The Dash team uses integration tests extensively, and we highly encourage you to write tests for the main functionality of your component. In the `tests` folder of the boilerplate, you can see a sample integration test. By launching it, you will run a sample Dash app in a browser. You can run the test with:
37 | ```
38 | python -m tests.test_render
39 | ```
40 | [Browse the Dash component code on GitHub for more examples of testing.](https://github.com/plotly/dash-core-components)
41 |
42 | ## Ready to publish? Final scan
43 |
44 | - Take a last look at the external resources that your component is using. Are all the external resources used [referenced in `MANIFEST.in`](https://github.com/plotly/dash-docs/blob/0b2fd8f892db720a7f3dc1c404b4cff464b5f8d4/tutorial/plugins.py#L55)?
45 |
46 | - You're ready to publish! Continue to [step #9 here](README.md#publishing).
--------------------------------------------------------------------------------
/src/lib/components/dash_draggable.react.js:
--------------------------------------------------------------------------------
1 | import React, {Component} from 'react';
2 | import PropTypes from 'prop-types';
3 | import Draggable from 'react-draggable';
4 |
5 | /**
6 | * ...
7 | */
8 | class dash_draggable extends Component {
9 | constructor(props) {
10 | super(props);
11 | this.state = {};
12 |
13 | this.handleOnDragStop = this.handleOnDragStop.bind(this);
14 | }
15 |
16 | handleOnDragStop(event, data) {
17 | console.log(event);
18 | console.log(data);
19 | this.props.setProps({
20 | lastX: data.lastX,
21 | lastY: data.lastY,
22 | // deltaX: data.deltaX,
23 | // deltaY: data.deltaY,
24 | });
25 | if (data.deltaX !==0 || data.deltaY !==0) {
26 | this.props.setProps({
27 | moved: true,
28 | });
29 | }
30 | else {
31 | this.props.setProps({
32 | moved: false,
33 | });}
34 | }
35 |
36 | render() {
37 | return (
38 |
39 |
47 |
48 | {this.props.children}
49 |
50 |
51 |
52 | );
53 | }
54 | }
55 |
56 | dash_draggable.defaultProps = {};
57 |
58 | dash_draggable.propTypes = {
59 | /**
60 | * The ID used to identify this component in Dash callbacks
61 | */
62 | id: PropTypes.string,
63 |
64 | /**
65 | * Dash-assigned callback that should be called whenever any of the
66 | * properties change
67 | */
68 | setProps: PropTypes.func,
69 |
70 | /**
71 | * ...
72 | */
73 | onStop: PropTypes.func,
74 |
75 | /**
76 | * ...
77 | */
78 | axis: PropTypes.string,
79 |
80 | /**
81 | * ...
82 | */
83 | handle: PropTypes.string,
84 |
85 | /**
86 | * ...
87 | */
88 | defaultPosition: PropTypes.object,
89 |
90 | /**
91 | * ...
92 | */
93 | position: PropTypes.object,
94 |
95 | /**
96 | * ...
97 | */
98 | grid: PropTypes.array,
99 |
100 | /**
101 | * ...
102 | */
103 | lastX: PropTypes.number,
104 |
105 | /**
106 | * ...
107 | */
108 | lastY: PropTypes.number,
109 |
110 | /**
111 | * ...
112 | */
113 | deltaX: PropTypes.number,
114 |
115 | /**
116 | * ...
117 | */
118 | deltaY: PropTypes.number,
119 |
120 | /**
121 | * ...
122 | */
123 | moved: PropTypes.bool,
124 |
125 | /**
126 | * ...
127 | */
128 | children: PropTypes.node,
129 |
130 | /**
131 | * ...
132 | */
133 | disabled: PropTypes.bool
134 | };
135 |
136 | export default dash_draggable;
137 |
--------------------------------------------------------------------------------
/dash_draggable/metadata.json:
--------------------------------------------------------------------------------
1 | {
2 | "src/lib/components/dash_draggable.react.js": {
3 | "description": "...",
4 | "displayName": "dash_draggable",
5 | "methods": [
6 | {
7 | "name": "handleOnDragStop",
8 | "docblock": null,
9 | "modifiers": [],
10 | "params": [
11 | {
12 | "name": "event",
13 | "type": null
14 | },
15 | {
16 | "name": "data",
17 | "type": null
18 | }
19 | ],
20 | "returns": null
21 | }
22 | ],
23 | "props": {
24 | "id": {
25 | "type": {
26 | "name": "string"
27 | },
28 | "required": false,
29 | "description": "The ID used to identify this component in Dash callbacks"
30 | },
31 | "setProps": {
32 | "type": {
33 | "name": "func"
34 | },
35 | "required": false,
36 | "description": "Dash-assigned callback that should be called whenever any of the\nproperties change"
37 | },
38 | "onStop": {
39 | "type": {
40 | "name": "func"
41 | },
42 | "required": false,
43 | "description": "..."
44 | },
45 | "axis": {
46 | "type": {
47 | "name": "string"
48 | },
49 | "required": false,
50 | "description": "..."
51 | },
52 | "handle": {
53 | "type": {
54 | "name": "string"
55 | },
56 | "required": false,
57 | "description": "..."
58 | },
59 | "defaultPosition": {
60 | "type": {
61 | "name": "object"
62 | },
63 | "required": false,
64 | "description": "..."
65 | },
66 | "position": {
67 | "type": {
68 | "name": "object"
69 | },
70 | "required": false,
71 | "description": "..."
72 | },
73 | "grid": {
74 | "type": {
75 | "name": "array"
76 | },
77 | "required": false,
78 | "description": "..."
79 | },
80 | "lastX": {
81 | "type": {
82 | "name": "number"
83 | },
84 | "required": false,
85 | "description": "..."
86 | },
87 | "lastY": {
88 | "type": {
89 | "name": "number"
90 | },
91 | "required": false,
92 | "description": "..."
93 | },
94 | "deltaX": {
95 | "type": {
96 | "name": "number"
97 | },
98 | "required": false,
99 | "description": "..."
100 | },
101 | "deltaY": {
102 | "type": {
103 | "name": "number"
104 | },
105 | "required": false,
106 | "description": "..."
107 | },
108 | "moved": {
109 | "type": {
110 | "name": "bool"
111 | },
112 | "required": false,
113 | "description": "..."
114 | },
115 | "children": {
116 | "type": {
117 | "name": "node"
118 | },
119 | "required": false,
120 | "description": "..."
121 | },
122 | "disabled": {
123 | "type": {
124 | "name": "bool"
125 | },
126 | "required": false,
127 | "description": "..."
128 | }
129 | }
130 | }
131 | }
132 |
--------------------------------------------------------------------------------
/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "extends": ["eslint:recommended", "prettier"],
3 | "parser": "babel-eslint",
4 | "parserOptions": {
5 | "ecmaVersion": 6,
6 | "sourceType": "module",
7 | "ecmaFeatures": {
8 | "arrowFunctions": true,
9 | "blockBindings": true,
10 | "classes": true,
11 | "defaultParams": true,
12 | "destructuring": true,
13 | "forOf": true,
14 | "generators": true,
15 | "modules": true,
16 | "templateStrings": true,
17 | "jsx": true
18 | }
19 | },
20 | "env": {
21 | "browser": true,
22 | "es6": true,
23 | "jasmine": true,
24 | "jest": true,
25 | "node": true
26 | },
27 | "globals": {
28 | "jest": true
29 | },
30 | "plugins": [
31 | "react",
32 | "import"
33 | ],
34 | "rules": {
35 | "accessor-pairs": ["error"],
36 | "block-scoped-var": ["error"],
37 | "consistent-return": ["error"],
38 | "curly": ["error", "all"],
39 | "default-case": ["error"],
40 | "dot-location": ["off"],
41 | "dot-notation": ["error"],
42 | "eqeqeq": ["error"],
43 | "guard-for-in": ["off"],
44 | "import/named": ["off"],
45 | "import/no-duplicates": ["error"],
46 | "import/no-named-as-default": ["error"],
47 | "new-cap": ["error"],
48 | "no-alert": [1],
49 | "no-caller": ["error"],
50 | "no-case-declarations": ["error"],
51 | "no-console": ["off"],
52 | "no-div-regex": ["error"],
53 | "no-dupe-keys": ["error"],
54 | "no-else-return": ["error"],
55 | "no-empty-pattern": ["error"],
56 | "no-eq-null": ["error"],
57 | "no-eval": ["error"],
58 | "no-extend-native": ["error"],
59 | "no-extra-bind": ["error"],
60 | "no-extra-boolean-cast": ["error"],
61 | "no-inline-comments": ["error"],
62 | "no-implicit-coercion": ["error"],
63 | "no-implied-eval": ["error"],
64 | "no-inner-declarations": ["off"],
65 | "no-invalid-this": ["error"],
66 | "no-iterator": ["error"],
67 | "no-labels": ["error"],
68 | "no-lone-blocks": ["error"],
69 | "no-loop-func": ["error"],
70 | "no-multi-str": ["error"],
71 | "no-native-reassign": ["error"],
72 | "no-new": ["error"],
73 | "no-new-func": ["error"],
74 | "no-new-wrappers": ["error"],
75 | "no-param-reassign": ["error"],
76 | "no-process-env": ["warn"],
77 | "no-proto": ["error"],
78 | "no-redeclare": ["error"],
79 | "no-return-assign": ["error"],
80 | "no-script-url": ["error"],
81 | "no-self-compare": ["error"],
82 | "no-sequences": ["error"],
83 | "no-shadow": ["off"],
84 | "no-throw-literal": ["error"],
85 | "no-undefined": ["error"],
86 | "no-unused-expressions": ["error"],
87 | "no-use-before-define": ["error", "nofunc"],
88 | "no-useless-call": ["error"],
89 | "no-useless-concat": ["error"],
90 | "no-with": ["error"],
91 | "prefer-const": ["error"],
92 | "radix": ["error"],
93 | "react/jsx-no-duplicate-props": ["error"],
94 | "react/jsx-no-undef": ["error"],
95 | "react/jsx-uses-react": ["error"],
96 | "react/jsx-uses-vars": ["error"],
97 | "react/no-did-update-set-state": ["error"],
98 | "react/no-direct-mutation-state": ["error"],
99 | "react/no-is-mounted": ["error"],
100 | "react/no-unknown-property": ["error"],
101 | "react/prefer-es6-class": ["error", "always"],
102 | "react/prop-types": "error",
103 | "valid-jsdoc": ["off"],
104 | "yoda": ["error"],
105 | "spaced-comment": ["error", "always", {
106 | "block": {
107 | exceptions: ["*"]
108 | }
109 | }],
110 | "no-unused-vars": ["error", {
111 | "args": "after-used",
112 | "argsIgnorePattern": "^_",
113 | "caughtErrorsIgnorePattern": "^e$"
114 | }],
115 | "no-magic-numbers": ["error", {
116 | "ignoreArrayIndexes": true,
117 | "ignore": [-1, 0, 1, 2, 3, 100, 10, 0.5]
118 | }],
119 | "no-underscore-dangle": ["off"]
120 | }
121 | }
122 |
--------------------------------------------------------------------------------
/usage.py:
--------------------------------------------------------------------------------
1 | import dash_draggable
2 | import dash
3 | from dash.dependencies import Input, Output
4 | import dash_html_components as html
5 | import dash_core_components as dcc
6 | import plotly.graph_objs as go
7 | import dash_daq as daq
8 |
9 |
10 | app = dash.Dash(__name__)
11 |
12 | app.scripts.config.serve_locally = True
13 | app.css.config.serve_locally = True
14 | app.config['suppress_callback_exceptions'] = True
15 |
16 | app.layout = html.Div([
17 | daq.BooleanSwitch(id='toggle-drag', on=True),
18 | html.Div(id='status'),
19 | html.Div(id='print'),
20 | html.Div(
21 | style={'width': '30vw', 'display': 'inline-flex'},
22 | children=dash_draggable.dash_draggable(
23 | id='draggable',
24 | axis="both",
25 | handle=".handle",
26 | defaultPosition={'x': 0, 'y': 100},
27 | position=None,
28 | grid=[12, 12],
29 | children=[
30 | html.Div(
31 | id='a-div',
32 | className='handle',
33 | children=dcc.Graph(
34 | id='example-graph',
35 | figure={
36 | 'data': [
37 | {'x': [1, 2, 3], 'y': [4, 1, 2], 'type': 'bar',
38 | 'name': 'SF'},
39 | {'x': [1, 2, 3], 'y': [2, 4, 5], 'type': 'bar',
40 | 'name': u'Montréal'},
41 | ],
42 | 'layout': {
43 | 'title': 'Drag anywhere'
44 | }
45 | }
46 | )
47 | )
48 | ]
49 | )),
50 |
51 | html.Div(
52 | style={'width': '30vw', 'display': 'inline-flex'},
53 | children=dash_draggable.dash_draggable(
54 | id='draggable-2',
55 | axis='x',
56 | handle='.handle',
57 | defaultPosition={'x': 200, 'y': 100},
58 | position=None,
59 | grid=[25, 25],
60 | children=[
61 | html.Div(
62 | id='another-div',
63 | className='handle',
64 | children=[
65 | dcc.Graph(
66 | id='example2',
67 | figure=dict(
68 | data=[go.Pie(
69 | labels=['Oxygen', 'Hydrogen',
70 | 'Carbon_Dioxide',
71 | 'Nitrogen'],
72 | values=[4500, 2500, 1053, 500],
73 | )],
74 | layout=dict(
75 | title='Drag horizontally'
76 | )
77 | )
78 | )
79 | ]
80 | )
81 | ]
82 | ))
83 | ])
84 |
85 |
86 | @app.callback(
87 | Output('print', 'children'),
88 | [Input('draggable', 'deltaX'),
89 | Input('draggable', 'deltaY')]
90 | )
91 | def print_test(event, position):
92 | return html.Div([html.P("{}".format(position)),
93 | html.P("{}".format(event))])
94 |
95 |
96 | # Disable/Enable dragging on component
97 | @app.callback(
98 | Output('draggable', 'disabled'),
99 | [Input('toggle-drag', 'on')]
100 | )
101 | def toggle_drag(toggle_status):
102 | # True/False
103 | return not toggle_status
104 |
105 |
106 | # Tell user if dragging is enabled and for which component
107 | @app.callback(
108 | Output('status', 'children'),
109 | [Input('toggle-drag', 'on')]
110 | )
111 | def can_drag(toggle_status):
112 | return html.P("'Drag Anywhere' Component Draggable: {}".format(toggle_status))
113 |
114 |
115 | if __name__ == '__main__':
116 | app.run_server(debug=True)
117 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Dash Draggable
2 |
3 | 
4 | 
5 |
6 | Dash Draggable is a Dash component library.
7 |
8 | Get started with:
9 | 1. Install Dash and its dependencies: https://dash.plot.ly/installation
10 | 2. Run `python usage.py`
11 | 3. Visit http://localhost:8050 in your web browser
12 |
13 | ## Contributing
14 |
15 | See [CONTRIBUTING.md](./CONTRIBUTING.md)
16 |
17 | ## Maintainers
18 | * @SterlingButters - Lead Maintainer
19 | * @xhlulu - Initial Work
20 |
21 | ### Install dependencies
22 |
23 | If you have selected install_dependencies during the prompt, you can skip this part.
24 |
25 | 1. Install npm packages
26 | ```
27 | $ npm install
28 | ```
29 | 2. Create a virtual env and activate.
30 | ```
31 | $ virtualenv venv
32 | $ venv/Scripts/activate
33 | ```
34 | _Note: venv\Scripts\activate for windows_
35 |
36 | 3. Install python packages required to build components.
37 | ```
38 | $ pip install -r requirements.txt
39 | ```
40 | 4. Install the python packages for testing (optional)
41 | ```
42 | $ pip install -r tests/requirements.txt
43 | ```
44 |
45 | ### Write your component code in `src/lib/components/dash_draggable.react.js`.
46 |
47 | - The demo app is in `src/demo` and you will import your example component code into your demo app.
48 | - Test your code in a Python environment:
49 | 1. Build your code
50 | ```
51 | $ npm run build:all
52 | ```
53 | 2. Run and modify the `usage.py` sample dash app:
54 | ```
55 | $ python usage.py
56 | ```
57 | - Write tests for your component.
58 | - A sample test is available in `tests/test_usage.py`, it will load `usage.py` and you can then automate interactions with selenium.
59 | - Run the tests with `$ pytest tests`.
60 | - The Dash team uses these types of integration tests extensively. Browse the Dash component code on GitHub for more examples of testing (e.g. https://github.com/plotly/dash-core-components)
61 | - Add custom styles to your component by putting your custom CSS files into your distribution folder (`dash_draggable`).
62 | - Make sure that they are referenced in `MANIFEST.in` so that they get properly included when you're ready to publish your component.
63 | - Make sure the stylesheets are added to the `_css_dist` dict in `dash_draggable/__init__.py` so dash will serve them automatically when the component suite is requested.
64 | - [Review your code](./review_checklist.md)
65 |
66 | ### Create a production build and publish:
67 |
68 | 1. Build your code:
69 | ```
70 | $ npm run build:all
71 | ```
72 | 2. Create a Python tarball
73 | ```
74 | $ python setup.py sdist
75 | ```
76 | This distribution tarball will get generated in the `dist/` folder
77 |
78 | 3. Test your tarball by copying it into a new environment and installing it locally:
79 | ```
80 | $ pip install dash_draggable-0.0.1.tar.gz
81 | ```
82 |
83 | 4. If it works, then you can publish the component to NPM and PyPI:
84 | 1. Cleanup the dist folder (optional)
85 | ```
86 | $ rm -rf dist
87 | ```
88 | 2. Publish on PyPI
89 | ```
90 | $ twine upload dist/*
91 | ```
92 | 3. Publish on NPM (Optional if chosen False in `publish_on_npm`)
93 | ```
94 | $ npm publish
95 | ```
96 | _Publishing your component to NPM will make the JavaScript bundles available on the unpkg CDN. By default, Dash servers the component library's CSS and JS from the remote unpkg CDN, so if you haven't published the component package to NPM you'll need to set the `serve_locally` flags to `True` (unless you choose `False` on `publish_on_npm`). We will eventually make `serve_locally=True` the default, [follow our progress in this issue](https://github.com/plotly/dash/issues/284)._
97 | 5. Share your component with the community! https://community.plot.ly/c/dash
98 | 1. Publish this repository to GitHub
99 | 2. Tag your GitHub repository with the plotly-dash tag so that it appears here: https://github.com/topics/plotly-dash
100 | 3. Create a post in the Dash community forum: https://community.plot.ly/c/dash
101 |
102 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
--------------------------------------------------------------------------------
/usage_prettyhandle.py:
--------------------------------------------------------------------------------
1 | import dash
2 | import dash_html_components as html
3 | from dash.dependencies import Output, Input, State
4 | import dash_core_components as dcc
5 | import dash_daq as daq
6 | import dash_draggable as drag
7 | from dash.exceptions import PreventUpdate
8 | import sd_material_ui
9 |
10 | external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']
11 |
12 | app = dash.Dash(external_stylesheets=external_stylesheets)
13 | app.config['suppress_callback_exceptions'] = True
14 |
15 | app.layout = html.Div([
16 |
17 | dcc.Store(id='position-store', storage_type='session', data={'lastXs': [200], 'lastYs': [0]}),
18 |
19 | drag.dash_draggable(id='dragger',
20 | handle='.handle',
21 | defaultPosition={'x': 200, 'y': 0},
22 | children=[
23 | html.Div([
24 | sd_material_ui.Paper(children=[
25 | sd_material_ui.IconButton(
26 | id='button',
27 | iconClassName='glyphicon glyphicon-menu-hamburger',
28 | iconStyle={'color': 'grey',
29 | 'width': 50,
30 | 'height': 50,
31 | 'position': 'relative',
32 | 'top': '2px',
33 | 'left': '-12px'},
34 | tooltip='Drag Me', touch=True,
35 | tooltipPosition='bottom-right')],
36 | zDepth=3,
37 | circle=True,
38 | style=dict(height=50,
39 | width=50,
40 | textAlign='center',
41 | position='relative',
42 | display='inline-block',
43 | top='25px',
44 | left='-25px')
45 | )], className='handle'),
46 |
47 | html.Div(id='graph-container')
48 | ]),
49 | ])
50 |
51 |
52 | ############################################################################
53 | # Commit last known position to memory
54 | @app.callback(
55 | Output('position-store', 'data'),
56 | [Input('dragger', 'lastX'),
57 | Input('dragger', 'lastY')],
58 | [State('position-store', 'data')]
59 | )
60 | def remember_position(lastX, lastY, data):
61 | data = data or {}
62 | x_history = data['lastXs'] or []
63 | y_history = data['lastYs'] or []
64 | if lastX is not None:
65 | x_history.append(lastX)
66 | if lastY is not None:
67 | y_history.append(lastY)
68 |
69 | data = {'lastXs': x_history, 'lastYs': y_history}
70 | return data
71 |
72 |
73 | ############################################################################
74 |
75 | @app.callback(
76 | Output('graph-container', 'children'),
77 | [Input('button', 'n_clicks'),
78 | Input('position-store', 'modified_timestamp')],
79 | [State('position-store', 'data'),
80 | State('graph-container', 'children')]
81 | )
82 | def hide_graph(clicked: int, timestamp, data, content):
83 | if timestamp is None:
84 | raise PreventUpdate
85 |
86 | xs = data.get('lastXs')
87 | ys = data.get('lastYs')
88 |
89 | if len(xs) > 1:
90 | x_prev = xs[-2]
91 | y_prev = ys[-2]
92 | x = xs[-1]
93 | y = ys[-1]
94 | else:
95 | x_prev = y_prev = x = y = None
96 |
97 | KNOB = sd_material_ui.Paper(zDepth=1,
98 | style=dict(height=625,
99 | width=750),
100 | children=[
101 | html.Div([
102 | daq.Knob(
103 | label="Gradient Ranges",
104 | value=7,
105 | size=500,
106 | color={"gradient": True,
107 | "ranges": {"red": [0, 5], "yellow": [5, 9],
108 | "green": [9, 10]}},
109 | style=dict(position='relative',
110 | top='25px',
111 | left='0px'))
112 | ])
113 | ]),
114 |
115 | if x_prev != x or y_prev != y: # Moved
116 | return content
117 | else:
118 | if content is None or content == []:
119 | return KNOB
120 | elif content:
121 | return []
122 |
123 |
124 |
125 | if __name__ == '__main__':
126 | app.css.append_css({'external_url': 'https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css'})
127 | app.run_server(debug=True)
128 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Created by .ignore support plugin (hsz.mobi)
2 | ### VisualStudioCode template
3 | .vscode/*
4 | !.vscode/settings.json
5 | !.vscode/tasks.json
6 | !.vscode/launch.json
7 | !.vscode/extensions.json
8 | ### JetBrains template
9 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm
10 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
11 |
12 | # User-specific stuff
13 | .idea/**/workspace.xml
14 | .idea/**/tasks.xml
15 | .idea/**/usage.statistics.xml
16 | .idea/**/dictionaries
17 | .idea/**/shelf
18 |
19 | # Sensitive or high-churn files
20 | .idea/**/dataSources/
21 | .idea/**/dataSources.ids
22 | .idea/**/dataSources.local.xml
23 | .idea/**/sqlDataSources.xml
24 | .idea/**/dynamic.xml
25 | .idea/**/uiDesigner.xml
26 | .idea/**/dbnavigator.xml
27 |
28 | # Gradle
29 | .idea/**/gradle.xml
30 | .idea/**/libraries
31 |
32 | # Gradle and Maven with auto-import
33 | # When using Gradle or Maven with auto-import, you should exclude module files,
34 | # since they will be recreated, and may cause churn. Uncomment if using
35 | # auto-import.
36 | # .idea/modules.xml
37 | # .idea/*.iml
38 | # .idea/modules
39 |
40 | # CMake
41 | cmake-build-*/
42 |
43 | # Mongo Explorer plugin
44 | .idea/**/mongoSettings.xml
45 |
46 | # File-based project format
47 | *.iws
48 |
49 | # IntelliJ
50 | out/
51 |
52 | # mpeltonen/sbt-idea plugin
53 | .idea_modules/
54 |
55 | # JIRA plugin
56 | atlassian-ide-plugin.xml
57 |
58 | # Cursive Clojure plugin
59 | .idea/replstate.xml
60 |
61 | # Crashlytics plugin (for Android Studio and IntelliJ)
62 | com_crashlytics_export_strings.xml
63 | crashlytics.properties
64 | crashlytics-build.properties
65 | fabric.properties
66 |
67 | # Editor-based Rest Client
68 | .idea/httpRequests
69 | ### Node template
70 | # Logs
71 | logs
72 | *.log
73 | npm-debug.log*
74 | yarn-debug.log*
75 | yarn-error.log*
76 |
77 | # Runtime data
78 | pids
79 | *.pid
80 | *.seed
81 | *.pid.lock
82 |
83 | # Directory for instrumented libs generated by jscoverage/JSCover
84 | lib-cov
85 |
86 | # Coverage directory used by tools like istanbul
87 | coverage
88 |
89 | # nyc test coverage
90 | .nyc_output
91 |
92 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
93 | .grunt
94 |
95 | # Bower dependency directory (https://bower.io/)
96 | bower_components
97 |
98 | # node-waf configuration
99 | .lock-wscript
100 |
101 | # Compiled binary addons (https://nodejs.org/api/addons.html)
102 | build/Release
103 |
104 | # Dependency directories
105 | node_modules/
106 | jspm_packages/
107 |
108 | # TypeScript v1 declaration files
109 | typings/
110 |
111 | # Optional npm cache directory
112 | .npm
113 |
114 | # Optional eslint cache
115 | .eslintcache
116 |
117 | # Optional REPL history
118 | .node_repl_history
119 |
120 | # Output of 'npm pack'
121 | *.tgz
122 |
123 | # Yarn Integrity file
124 | .yarn-integrity
125 |
126 | # dotenv environment variables file
127 | .env
128 |
129 | # parcel-bundler cache (https://parceljs.org/)
130 | .cache
131 |
132 | # next.js build output
133 | .next
134 |
135 | # nuxt.js build output
136 | .nuxt
137 |
138 | # vuepress build output
139 | .vuepress/dist
140 |
141 | # Serverless directories
142 | .serverless
143 | ### Python template
144 | # Byte-compiled / optimized / DLL files
145 | __pycache__/
146 | *.py[cod]
147 | *$py.class
148 |
149 | # C extensions
150 | *.so
151 |
152 | # Distribution / packaging
153 | .Python
154 | build/
155 | develop-eggs/
156 | dist/
157 | downloads/
158 | eggs/
159 | .eggs/
160 | lib64/
161 | parts/
162 | sdist/
163 | var/
164 | wheels/
165 | *.egg-info/
166 | .installed.cfg
167 | *.egg
168 | MANIFEST
169 |
170 | # PyInstaller
171 | # Usually these files are written by a python script from a template
172 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
173 | *.manifest
174 | *.spec
175 |
176 | # Installer logs
177 | pip-log.txt
178 | pip-delete-this-directory.txt
179 |
180 | # Unit test / coverage reports
181 | htmlcov/
182 | .tox/
183 | .coverage
184 | .coverage.*
185 | nosetests.xml
186 | coverage.xml
187 | *.cover
188 | .hypothesis/
189 | .pytest_cache/
190 |
191 | # Translations
192 | *.mo
193 | *.pot
194 |
195 | # Django stuff:
196 | local_settings.py
197 | db.sqlite3
198 |
199 | # Flask stuff:
200 | instance/
201 | .webassets-cache
202 |
203 | # Scrapy stuff:
204 | .scrapy
205 |
206 | # Sphinx documentation
207 | docs/_build/
208 |
209 | # PyBuilder
210 | target/
211 |
212 | # Jupyter Notebook
213 | .ipynb_checkpoints
214 |
215 | # pyenv
216 | .python-version
217 |
218 | # celery beat schedule file
219 | celerybeat-schedule
220 |
221 | # SageMath parsed files
222 | *.sage.py
223 |
224 | # Environments
225 | .venv
226 | env/
227 | venv/
228 | ENV/
229 | env.bak/
230 | venv.bak/
231 |
232 | # Spyder project settings
233 | .spyderproject
234 | .spyproject
235 |
236 | # Rope project settings
237 | .ropeproject
238 |
239 | # mkdocs documentation
240 | /site
241 |
242 | # mypy
243 | .mypy_cache/
244 | ### SublimeText template
245 | # Cache files for Sublime Text
246 | *.tmlanguage.cache
247 | *.tmPreferences.cache
248 | *.stTheme.cache
249 |
250 | # Workspace files are user-specific
251 | *.sublime-workspace
252 |
253 | # Project files should be checked into the repository, unless a significant
254 | # proportion of contributors will probably not be using Sublime Text
255 | # *.sublime-project
256 |
257 | # SFTP configuration file
258 | sftp-config.json
259 |
260 | # Package control specific files
261 | Package Control.last-run
262 | Package Control.ca-list
263 | Package Control.ca-bundle
264 | Package Control.system-ca-bundle
265 | Package Control.cache/
266 | Package Control.ca-certs/
267 | Package Control.merged-ca-bundle
268 | Package Control.user-ca-bundle
269 | oscrypto-ca-bundle.crt
270 | bh_unicode_properties.cache
271 |
272 | # Sublime-github package stores a github token in this file
273 | # https://packagecontrol.io/packages/sublime-github
274 | GitHub.sublime-settings
275 |
--------------------------------------------------------------------------------
/.pylintrc:
--------------------------------------------------------------------------------
1 | [MASTER]
2 |
3 | # A comma-separated list of package or module names from where C extensions may
4 | # be loaded. Extensions are loading into the active Python interpreter and may
5 | # run arbitrary code
6 | extension-pkg-whitelist=
7 |
8 | # Add files or directories to the blacklist. They should be base names, not
9 | # paths.
10 | ignore=CVS
11 |
12 | # Add files or directories matching the regex patterns to the blacklist. The
13 | # regex matches against base names, not paths.
14 | ignore-patterns=
15 |
16 | # Python code to execute, usually for sys.path manipulation such as
17 | # pygtk.require().
18 | #init-hook=
19 |
20 | # Use multiple processes to speed up Pylint.
21 | jobs=1
22 |
23 | # List of plugins (as comma separated values of python modules names) to load,
24 | # usually to register additional checkers.
25 | load-plugins=
26 |
27 | # Pickle collected data for later comparisons.
28 | persistent=yes
29 |
30 | # Specify a configuration file.
31 | #rcfile=
32 |
33 | # When enabled, pylint would attempt to guess common misconfiguration and emit
34 | # user-friendly hints instead of false-positive error messages
35 | suggestion-mode=yes
36 |
37 | # Allow loading of arbitrary C extensions. Extensions are imported into the
38 | # active Python interpreter and may run arbitrary code.
39 | unsafe-load-any-extension=no
40 |
41 |
42 | [MESSAGES CONTROL]
43 |
44 | # Only show warnings with the listed confidence levels. Leave empty to show
45 | # all. Valid levels: HIGH, INFERENCE, INFERENCE_FAILURE, UNDEFINED
46 | confidence=
47 |
48 | # Disable the message, report, category or checker with the given id(s). You
49 | # can either give multiple identifiers separated by comma (,) or put this
50 | # option multiple times (only on the command line, not in the configuration
51 | # file where it should appear only once).You can also use "--disable=all" to
52 | # disable everything first and then reenable specific checks. For example, if
53 | # you want to run only the similarities checker, you can use "--disable=all
54 | # --enable=similarities". If you want to run only the classes checker, but have
55 | # no Warning level messages displayed, use"--disable=all --enable=classes
56 | # --disable=W"
57 | disable=print-statement,
58 | parameter-unpacking,
59 | unpacking-in-except,
60 | old-raise-syntax,
61 | backtick,
62 | long-suffix,
63 | old-ne-operator,
64 | old-octal-literal,
65 | import-star-module-level,
66 | non-ascii-bytes-literal,
67 | raw-checker-failed,
68 | bad-inline-option,
69 | locally-disabled,
70 | locally-enabled,
71 | file-ignored,
72 | suppressed-message,
73 | useless-suppression,
74 | deprecated-pragma,
75 | apply-builtin,
76 | basestring-builtin,
77 | buffer-builtin,
78 | cmp-builtin,
79 | coerce-builtin,
80 | execfile-builtin,
81 | file-builtin,
82 | long-builtin,
83 | raw_input-builtin,
84 | reduce-builtin,
85 | standarderror-builtin,
86 | unicode-builtin,
87 | xrange-builtin,
88 | coerce-method,
89 | delslice-method,
90 | getslice-method,
91 | setslice-method,
92 | no-absolute-import,
93 | old-division,
94 | dict-iter-method,
95 | dict-view-method,
96 | next-method-called,
97 | metaclass-assignment,
98 | indexing-exception,
99 | raising-string,
100 | reload-builtin,
101 | oct-method,
102 | hex-method,
103 | nonzero-method,
104 | cmp-method,
105 | input-builtin,
106 | round-builtin,
107 | intern-builtin,
108 | unichr-builtin,
109 | map-builtin-not-iterating,
110 | zip-builtin-not-iterating,
111 | range-builtin-not-iterating,
112 | filter-builtin-not-iterating,
113 | using-cmp-argument,
114 | eq-without-hash,
115 | div-method,
116 | idiv-method,
117 | rdiv-method,
118 | exception-message-attribute,
119 | invalid-str-codec,
120 | sys-max-int,
121 | bad-python3-import,
122 | deprecated-string-function,
123 | deprecated-str-translate-call,
124 | deprecated-itertools-function,
125 | deprecated-types-field,
126 | next-method-defined,
127 | dict-items-not-iterating,
128 | dict-keys-not-iterating,
129 | dict-values-not-iterating,
130 | no-member,
131 | missing-docstring,
132 | invalid-name,
133 | redefined-builtin,
134 | wrong-import-order,
135 | too-many-arguments,
136 | too-many-locals,
137 | consider-using-enumerate,
138 | len-as-condition,
139 | too-many-branches,
140 | too-many-statements,
141 | blacklisted-name,
142 | line-too-long,
143 | bare-except,
144 | duplicate-code,
145 | too-many-function-args,
146 | attribute-defined-outside-init,
147 | broad-except
148 |
149 | # Enable the message, report, category or checker with the given id(s). You can
150 | # either give multiple identifier separated by comma (,) or put this option
151 | # multiple time (only on the command line, not in the configuration file where
152 | # it should appear only once). See also the "--disable" option for examples.
153 | enable=c-extension-no-member
154 |
155 |
156 | [REPORTS]
157 |
158 | # Python expression which should return a note less than 10 (10 is the highest
159 | # note). You have access to the variables errors warning, statement which
160 | # respectively contain the number of errors / warnings messages and the total
161 | # number of statements analyzed. This is used by the global evaluation report
162 | # (RP0004).
163 | evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10)
164 |
165 | # Template used to display messages. This is a python new-style format string
166 | # used to format the message information. See doc for all details
167 | #msg-template=
168 |
169 | # Set the output format. Available formats are text, parseable, colorized, json
170 | # and msvs (visual studio).You can also give a reporter class, eg
171 | # mypackage.mymodule.MyReporterClass.
172 | output-format=text
173 |
174 | # Tells whether to display a full report or only the messages
175 | reports=no
176 |
177 | # Activate the evaluation score.
178 | score=yes
179 |
180 |
181 | [REFACTORING]
182 |
183 | # Maximum number of nested blocks for function / method body
184 | max-nested-blocks=5
185 |
186 | # Complete name of functions that never returns. When checking for
187 | # inconsistent-return-statements if a never returning function is called then
188 | # it will be considered as an explicit return statement and no message will be
189 | # printed.
190 | never-returning-functions=optparse.Values,sys.exit
191 |
192 |
193 | [BASIC]
194 |
195 | # Naming style matching correct argument names
196 | argument-naming-style=snake_case
197 |
198 | # Regular expression matching correct argument names. Overrides argument-
199 | # naming-style
200 | #argument-rgx=
201 |
202 | # Naming style matching correct attribute names
203 | attr-naming-style=snake_case
204 |
205 | # Regular expression matching correct attribute names. Overrides attr-naming-
206 | # style
207 | #attr-rgx=
208 |
209 | # Bad variable names which should always be refused, separated by a comma
210 | bad-names=foo,
211 | bar,
212 | baz,
213 | toto,
214 | tutu,
215 | tata
216 |
217 | # Naming style matching correct class attribute names
218 | class-attribute-naming-style=any
219 |
220 | # Regular expression matching correct class attribute names. Overrides class-
221 | # attribute-naming-style
222 | #class-attribute-rgx=
223 |
224 | # Naming style matching correct class names
225 | class-naming-style=PascalCase
226 |
227 | # Regular expression matching correct class names. Overrides class-naming-style
228 | #class-rgx=
229 |
230 | # Naming style matching correct constant names
231 | const-naming-style=UPPER_CASE
232 |
233 | # Regular expression matching correct constant names. Overrides const-naming-
234 | # style
235 | #const-rgx=
236 |
237 | # Minimum line length for functions/classes that require docstrings, shorter
238 | # ones are exempt.
239 | docstring-min-length=-1
240 |
241 | # Naming style matching correct function names
242 | function-naming-style=snake_case
243 |
244 | # Regular expression matching correct function names. Overrides function-
245 | # naming-style
246 | #function-rgx=
247 |
248 | # Good variable names which should always be accepted, separated by a comma
249 | good-names=i,
250 | j,
251 | k,
252 | ex,
253 | Run,
254 | _
255 |
256 | # Include a hint for the correct naming format with invalid-name
257 | include-naming-hint=no
258 |
259 | # Naming style matching correct inline iteration names
260 | inlinevar-naming-style=any
261 |
262 | # Regular expression matching correct inline iteration names. Overrides
263 | # inlinevar-naming-style
264 | #inlinevar-rgx=
265 |
266 | # Naming style matching correct method names
267 | method-naming-style=snake_case
268 |
269 | # Regular expression matching correct method names. Overrides method-naming-
270 | # style
271 | #method-rgx=
272 |
273 | # Naming style matching correct module names
274 | module-naming-style=snake_case
275 |
276 | # Regular expression matching correct module names. Overrides module-naming-
277 | # style
278 | #module-rgx=
279 |
280 | # Colon-delimited sets of names that determine each other's naming style when
281 | # the name regexes allow several styles.
282 | name-group=
283 |
284 | # Regular expression which should only match function or class names that do
285 | # not require a docstring.
286 | no-docstring-rgx=^_
287 |
288 | # List of decorators that produce properties, such as abc.abstractproperty. Add
289 | # to this list to register other decorators that produce valid properties.
290 | property-classes=abc.abstractproperty
291 |
292 | # Naming style matching correct variable names
293 | variable-naming-style=snake_case
294 |
295 | # Regular expression matching correct variable names. Overrides variable-
296 | # naming-style
297 | #variable-rgx=
298 |
299 |
300 | [FORMAT]
301 |
302 | # Expected format of line ending, e.g. empty (any line ending), LF or CRLF.
303 | expected-line-ending-format=
304 |
305 | # Regexp for a line that is allowed to be longer than the limit.
306 | ignore-long-lines=^\s*(# )??$
307 |
308 | # Number of spaces of indent required inside a hanging or continued line.
309 | indent-after-paren=4
310 |
311 | # String used as indentation unit. This is usually " " (4 spaces) or "\t" (1
312 | # tab).
313 | indent-string=' '
314 |
315 | # Maximum number of characters on a single line.
316 | max-line-length=100
317 |
318 | # Maximum number of lines in a module
319 | max-module-lines=1000
320 |
321 | # List of optional constructs for which whitespace checking is disabled. `dict-
322 | # separator` is used to allow tabulation in dicts, etc.: {1 : 1,\n222: 2}.
323 | # `trailing-comma` allows a space between comma and closing bracket: (a, ).
324 | # `empty-line` allows space-only lines.
325 | no-space-check=trailing-comma,
326 | dict-separator
327 |
328 | # Allow the body of a class to be on the same line as the declaration if body
329 | # contains single statement.
330 | single-line-class-stmt=no
331 |
332 | # Allow the body of an if to be on the same line as the test if there is no
333 | # else.
334 | single-line-if-stmt=no
335 |
336 |
337 | [LOGGING]
338 |
339 | # Logging modules to check that the string format arguments are in logging
340 | # function parameter format
341 | logging-modules=logging
342 |
343 |
344 | [MISCELLANEOUS]
345 |
346 | # List of note tags to take in consideration, separated by a comma.
347 | notes=FIXME,
348 | XXX,
349 |
350 |
351 | [SIMILARITIES]
352 |
353 | # Ignore comments when computing similarities.
354 | ignore-comments=yes
355 |
356 | # Ignore docstrings when computing similarities.
357 | ignore-docstrings=yes
358 |
359 | # Ignore imports when computing similarities.
360 | ignore-imports=no
361 |
362 | # Minimum lines number of a similarity.
363 | min-similarity-lines=4
364 |
365 |
366 | [SPELLING]
367 |
368 | # Limits count of emitted suggestions for spelling mistakes
369 | max-spelling-suggestions=4
370 |
371 | # Spelling dictionary name. Available dictionaries: none. To make it working
372 | # install python-enchant package.
373 | spelling-dict=
374 |
375 | # List of comma separated words that should not be checked.
376 | spelling-ignore-words=
377 |
378 | # A path to a file that contains private dictionary; one word per line.
379 | spelling-private-dict-file=
380 |
381 | # Tells whether to store unknown words to indicated private dictionary in
382 | # --spelling-private-dict-file option instead of raising a message.
383 | spelling-store-unknown-words=no
384 |
385 |
386 | [TYPECHECK]
387 |
388 | # List of decorators that produce context managers, such as
389 | # contextlib.contextmanager. Add to this list to register other decorators that
390 | # produce valid context managers.
391 | contextmanager-decorators=contextlib.contextmanager
392 |
393 | # List of members which are set dynamically and missed by pylint inference
394 | # system, and so shouldn't trigger E1101 when accessed. Python regular
395 | # expressions are accepted.
396 | generated-members=
397 |
398 | # Tells whether missing members accessed in mixin class should be ignored. A
399 | # mixin class is detected if its name ends with "mixin" (case insensitive).
400 | ignore-mixin-members=yes
401 |
402 | # This flag controls whether pylint should warn about no-member and similar
403 | # checks whenever an opaque object is returned when inferring. The inference
404 | # can return multiple potential results while evaluating a Python object, but
405 | # some branches might not be evaluated, which results in partial inference. In
406 | # that case, it might be useful to still emit no-member and other checks for
407 | # the rest of the inferred objects.
408 | ignore-on-opaque-inference=yes
409 |
410 | # List of class names for which member attributes should not be checked (useful
411 | # for classes with dynamically set attributes). This supports the use of
412 | # qualified names.
413 | ignored-classes=optparse.Values,thread._local,_thread._local
414 |
415 | # List of module names for which member attributes should not be checked
416 | # (useful for modules/projects where namespaces are manipulated during runtime
417 | # and thus existing member attributes cannot be deduced by static analysis. It
418 | # supports qualified module names, as well as Unix pattern matching.
419 | ignored-modules=
420 |
421 | # Show a hint with possible names when a member name was not found. The aspect
422 | # of finding the hint is based on edit distance.
423 | missing-member-hint=yes
424 |
425 | # The minimum edit distance a name should have in order to be considered a
426 | # similar match for a missing member name.
427 | missing-member-hint-distance=1
428 |
429 | # The total number of similar names that should be taken in consideration when
430 | # showing a hint for a missing member.
431 | missing-member-max-choices=1
432 |
433 |
434 | [VARIABLES]
435 |
436 | # List of additional names supposed to be defined in builtins. Remember that
437 | # you should avoid to define new builtins when possible.
438 | additional-builtins=
439 |
440 | # Tells whether unused global variables should be treated as a violation.
441 | allow-global-unused-variables=yes
442 |
443 | # List of strings which can identify a callback function by name. A callback
444 | # name must start or end with one of those strings.
445 | callbacks=cb_,
446 | _cb
447 |
448 | # A regular expression matching the name of dummy variables (i.e. expectedly
449 | # not used).
450 | dummy-variables-rgx=_+$|(_[a-zA-Z0-9_]*[a-zA-Z0-9]+?$)|dummy|^ignored_|^unused_
451 |
452 | # Argument names that match this expression will be ignored. Default to name
453 | # with leading underscore
454 | ignored-argument-names=_.*|^ignored_|^unused_
455 |
456 | # Tells whether we should check for unused import in __init__ files.
457 | init-import=no
458 |
459 | # List of qualified module names which can have objects that can redefine
460 | # builtins.
461 | redefining-builtins-modules=six.moves,past.builtins,future.builtins
462 |
463 |
464 | [CLASSES]
465 |
466 | # List of method names used to declare (i.e. assign) instance attributes.
467 | defining-attr-methods=__init__,
468 | __new__,
469 | setUp
470 |
471 | # List of member names, which should be excluded from the protected access
472 | # warning.
473 | exclude-protected=_asdict,
474 | _fields,
475 | _replace,
476 | _source,
477 | _make
478 |
479 | # List of valid names for the first argument in a class method.
480 | valid-classmethod-first-arg=cls
481 |
482 | # List of valid names for the first argument in a metaclass class method.
483 | valid-metaclass-classmethod-first-arg=mcs
484 |
485 |
486 | [DESIGN]
487 |
488 | # Maximum number of arguments for function / method
489 | max-args=5
490 |
491 | # Maximum number of attributes for a class (see R0902).
492 | max-attributes=7
493 |
494 | # Maximum number of boolean expressions in a if statement
495 | max-bool-expr=5
496 |
497 | # Maximum number of branch for function / method body
498 | max-branches=12
499 |
500 | # Maximum number of locals for function / method body
501 | max-locals=15
502 |
503 | # Maximum number of parents for a class (see R0901).
504 | max-parents=7
505 |
506 | # Maximum number of public methods for a class (see R0904).
507 | max-public-methods=20
508 |
509 | # Maximum number of return / yield for function / method body
510 | max-returns=6
511 |
512 | # Maximum number of statements in function / method body
513 | max-statements=50
514 |
515 | # Minimum number of public methods for a class (see R0903).
516 | min-public-methods=2
517 |
518 |
519 | [IMPORTS]
520 |
521 | # Allow wildcard imports from modules that define __all__.
522 | allow-wildcard-with-all=no
523 |
524 | # Analyse import fallback blocks. This can be used to support both Python 2 and
525 | # 3 compatible code, which means that the block might have code that exists
526 | # only in one or another interpreter, leading to false positives when analysed.
527 | analyse-fallback-blocks=no
528 |
529 | # Deprecated modules which should not be used, separated by a comma
530 | deprecated-modules=optparse,tkinter.tix
531 |
532 | # Create a graph of external dependencies in the given file (report RP0402 must
533 | # not be disabled)
534 | ext-import-graph=
535 |
536 | # Create a graph of every (i.e. internal and external) dependencies in the
537 | # given file (report RP0402 must not be disabled)
538 | import-graph=
539 |
540 | # Create a graph of internal dependencies in the given file (report RP0402 must
541 | # not be disabled)
542 | int-import-graph=
543 |
544 | # Force import order to recognize a module as part of the standard
545 | # compatibility libraries.
546 | known-standard-library=
547 |
548 | # Force import order to recognize a module as part of a third party library.
549 | known-third-party=enchant
550 |
551 |
552 | [EXCEPTIONS]
553 |
554 | # Exceptions that will emit a warning when being caught. Defaults to
555 | # "Exception"
556 | overgeneral-exceptions=Exception
557 |
--------------------------------------------------------------------------------
/dash_draggable/dash_draggable.min.js:
--------------------------------------------------------------------------------
1 | window.dash_draggable=function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=1)}([function(e,t){e.exports=window.React},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.dash_draggable=void 0;var r,o=n(2),a=(r=o)&&r.__esModule?r:{default:r};t.dash_draggable=a.default},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=function(){function e(e,t){for(var n=0;n2?n-2:0),o=2;o1?t-1:0),r=1;r>",i={array:f("array"),bool:f("boolean"),func:f("function"),number:f("number"),object:f("object"),string:f("string"),symbol:f("symbol"),any:c(a.thatReturnsNull),arrayOf:function(e){return c(function(t,n,r,o,a){if("function"!=typeof e)return new l("Property `"+a+"` of component `"+r+"` has invalid PropType notation inside arrayOf.");var i=t[n];if(!Array.isArray(i)){var s=h(i);return new l("Invalid "+o+" `"+a+"` of type `"+s+"` supplied to `"+r+"`, expected an array.")}for(var u=0;u0&&void 0!==arguments[0]?arguments[0]:"transform";if("undefined"==typeof window||void 0===window.document)return"";var t=window.document.documentElement.style;if(e in t)return"";for(var n=0;n0&&void 0!==arguments[0]?arguments[0]:{};return C({touchAction:"none"},e)}function J(e){return"both"===e.props.axis||"x"===e.props.axis}function $(e){return"both"===e.props.axis||"y"===e.props.axis}function K(e,t,n){var r="number"==typeof t?function(e,t){return e.targetTouches&&O(e.targetTouches,function(e){return t===e.identifier})||e.changedTouches&&O(e.changedTouches,function(e){return t===e.identifier})}(e,t):null;if("number"==typeof t&&!r)return null;var o=ee(n),a=n.props.offsetParent||o.offsetParent||o.ownerDocument.body;return function(e,t){var n=t===t.ownerDocument.body?{left:0,top:0}:t.getBoundingClientRect(),r=e.clientX+t.scrollLeft-n.left,o=e.clientY+t.scrollTop-n.top;return{x:r,y:o}}(r||e,a)}function Q(e,t,n){var r=e.state,o=!D(r.lastX),a=ee(e);return o?{node:a,deltaX:0,deltaY:0,lastX:t,lastY:n,x:t,y:n}:{node:a,deltaX:t-r.lastX,deltaY:n-r.lastY,lastX:r.lastX,lastY:r.lastY,x:t,y:n}}function Z(e,t){var n=e.props.scale;return{node:t.node,x:e.state.x+t.deltaX/n,y:e.state.y+t.deltaY/n,deltaX:t.deltaX/n,deltaY:t.deltaY/n,lastX:e.state.x,lastY:e.state.y}}function ee(t){var n=e.findDOMNode(t);if(!n)throw new Error(": Unmounted during event!");return n}var te={touch:{start:"touchstart",move:"touchmove",stop:"touchend"},mouse:{start:"mousedown",move:"mousemove",stop:"mouseup"}},ne=te.mouse,re=function(n){function r(){var t,n,o;_(this,r);for(var a=arguments.length,i=Array(a),s=0;s not mounted on DragStart!");var r=n.ownerDocument;if(!(o.props.disabled||!(t.target instanceof r.defaultView.Node)||o.props.handle&&!L(t.target,o.props.handle,n)||o.props.cancel&&L(t.target,o.props.cancel,n))){var a=function(e){return e.targetTouches&&e.targetTouches[0]?e.targetTouches[0].identifier:e.changedTouches&&e.changedTouches[0]?e.changedTouches[0].identifier:void 0}(t);o.setState({touchIdentifier:a});var i=K(t,a,o);if(null!=i){var s=i.x,u=i.y,l=Q(o,s,u);o.props.onStart;var c=o.props.onStart(t,l);!1!==c&&(o.props.enableUserSelectHack&&F(r),o.setState({dragging:!0,lastX:s,lastY:u}),U(r,ne.move,o.handleDrag),U(r,ne.stop,o.handleDragStop))}}},o.handleDrag=function(e){"touchmove"===e.type&&e.preventDefault();var t=K(e,o.state.touchIdentifier,o);if(null!=t){var n=t.x,r=t.y;if(Array.isArray(o.props.grid)){var a=n-o.state.lastX,i=r-o.state.lastY,s=function(e,t,n){var r=Math.round(t/e[0])*e[0],o=Math.round(n/e[1])*e[1];return[r,o]}(o.props.grid,a,i),u=I(s,2);if(a=u[0],i=u[1],!a&&!i)return;n=o.state.lastX+a,r=o.state.lastY+i}var l=Q(o,n,r),c=o.props.onDrag(e,l);if(!1!==c)o.setState({lastX:n,lastY:r});else try{o.handleDragStop(new MouseEvent("mouseup"))}catch(e){var f=document.createEvent("MouseEvents");f.initMouseEvent("mouseup",!0,!0,window,0,0,0,0,0,!1,!1,!1,!1,0,null),o.handleDragStop(f)}}},o.handleDragStop=function(t){if(o.state.dragging){var n=K(t,o.state.touchIdentifier,o);if(null!=n){var r=n.x,a=n.y,i=Q(o,r,a),s=e.findDOMNode(o);s&&o.props.enableUserSelectHack&&G(s.ownerDocument),o.setState({dragging:!1,lastX:NaN,lastY:NaN}),o.props.onStop(t,i),s&&(W(s.ownerDocument,ne.move,o.handleDrag),W(s.ownerDocument,ne.stop,o.handleDragStop))}}},o.onMouseDown=function(e){return ne=te.mouse,o.handleDragStart(e)},o.onMouseUp=function(e){return ne=te.mouse,o.handleDragStop(e)},o.onTouchStart=function(e){return ne=te.touch,o.handleDragStart(e)},o.onTouchEnd=function(e){return ne=te.touch,o.handleDragStop(e)},Y(o,n)}return R(r,n),N(r,[{key:"componentWillUnmount",value:function(){var t=e.findDOMNode(this);if(t){var n=t.ownerDocument;W(n,te.mouse.move,this.handleDrag),W(n,te.touch.move,this.handleDrag),W(n,te.mouse.stop,this.handleDragStop),W(n,te.touch.stop,this.handleDragStop),this.props.enableUserSelectHack&&G(n)}}},{key:"render",value:function(){return t.cloneElement(t.Children.only(this.props.children),{style:z(this.props.children.props.style),onMouseDown:this.onMouseDown,onTouchStart:this.onTouchStart,onMouseUp:this.onMouseUp,onTouchEnd:this.onTouchEnd})}}]),r}(t.Component);re.displayName="DraggableCore",re.propTypes={allowAnyClick:w.bool,disabled:w.bool,enableUserSelectHack:w.bool,offsetParent:function(e,t){if(e[t]&&1!==e[t].nodeType)throw new Error("Draggable's offsetParent must be a DOM Node.")},grid:w.arrayOf(w.number),scale:w.number,handle:w.string,cancel:w.string,onStart:w.func,onDrag:w.func,onStop:w.func,onMouseDown:w.func,className:E,style:E,transform:E},re.defaultProps={allowAnyClick:!1,cancel:null,disabled:!1,enableUserSelectHack:!0,offsetParent:null,handle:null,grid:null,transform:null,onStart:function(){},onDrag:function(){},onStop:function(){},onMouseDown:function(){}};var oe=function(n){function r(e){_(this,r);var t=Y(this,(r.__proto__||Object.getPrototypeOf(r)).call(this,e));return t.onDragStart=function(e,n){var r=t.props.onStart(e,Z(t,n));if(!1===r)return!1;t.setState({dragging:!0,dragged:!0})},t.onDrag=function(e,n){if(!t.state.dragging)return!1;var r=Z(t,n),o={x:r.x,y:r.y};if(t.props.bounds){var a=o.x,i=o.y;o.x+=t.state.slackX,o.y+=t.state.slackY;var s=function(e,t,n){if(!e.props.bounds)return[t,n];var r=e.props.bounds;r="string"==typeof r?r:function(e){return{left:e.left,top:e.top,right:e.right,bottom:e.bottom}}(r);var o=ee(e);if("string"==typeof r){var a=o.ownerDocument,i=a.defaultView,s=void 0;if(!((s="parent"===r?o.parentNode:a.querySelector(r))instanceof i.HTMLElement))throw new Error('Bounds selector "'+r+'" could not find an element.');var u=i.getComputedStyle(o),l=i.getComputedStyle(s);r={left:-o.offsetLeft+T(l.paddingLeft)+T(u.marginLeft),top:-o.offsetTop+T(l.paddingTop)+T(u.marginTop),right:q(s)-B(o)-o.offsetLeft+T(l.paddingRight)-T(u.marginRight),bottom:H(s)-V(o)-o.offsetTop+T(l.paddingBottom)-T(u.marginBottom)}}return D(r.right)&&(t=Math.min(t,r.right)),D(r.bottom)&&(n=Math.min(n,r.bottom)),D(r.left)&&(t=Math.max(t,r.left)),D(r.top)&&(n=Math.max(n,r.top)),[t,n]}(t,o.x,o.y),u=I(s,2),l=u[0],c=u[1];o.x=l,o.y=c,o.slackX=t.state.slackX+(a-o.x),o.slackY=t.state.slackY+(i-o.y),r.x=o.x,r.y=o.y,r.deltaX=o.x-t.state.x,r.deltaY=o.y-t.state.y}var f=t.props.onDrag(e,r);if(!1===f)return!1;t.setState(o)},t.onDragStop=function(e,n){if(!t.state.dragging)return!1;var r=t.props.onStop(e,Z(t,n));if(!1===r)return!1;var o={dragging:!1,slackX:0,slackY:0},a=Boolean(t.props.position);if(a){var i=t.props.position,s=i.x,u=i.y;o.x=s,o.y=u}t.setState(o)},t.state={dragging:!1,dragged:!1,x:e.position?e.position.x:e.defaultPosition.x,y:e.position?e.position.y:e.defaultPosition.y,slackX:0,slackY:0,isElementSVG:!1},t}return R(r,n),N(r,[{key:"componentWillMount",value:function(){!this.props.position||this.props.onDrag||this.props.onStop||console.warn("A `position` was applied to this , without drag handlers. This will make this component effectively undraggable. Please attach `onDrag` or `onStop` handlers so you can adjust the `position` of this element.")}},{key:"componentDidMount",value:function(){void 0!==window.SVGElement&&e.findDOMNode(this)instanceof window.SVGElement&&this.setState({isElementSVG:!0})}},{key:"componentWillReceiveProps",value:function(e){!e.position||this.props.position&&e.position.x===this.props.position.x&&e.position.y===this.props.position.y||this.setState({x:e.position.x,y:e.position.y})}},{key:"componentWillUnmount",value:function(){this.setState({dragging:!1})}},{key:"render",value:function(){var e,n,r,o,a={},i=null,s=Boolean(this.props.position),u=!s||this.state.dragging,l=this.props.position||this.props.defaultPosition,c={x:J(this)&&u?this.state.x:l.x,y:$(this)&&u?this.state.y:l.y};this.state.isElementSVG?(r=(n=c).x,o=n.y,i="translate("+r+","+o+")"):a=function(e){var t=e.x,n=e.y;return M({},P("transform",k),"translate("+t+"px,"+n+"px)")}(c);var f=this.props,p=f.defaultClassName,d=f.defaultClassNameDragging,g=f.defaultClassNameDragged,h=t.Children.only(this.props.children),y=S(h.props.className||"",p,(M(e={},d,this.state.dragging),M(e,g,this.state.dragged),e));return t.createElement(re,C({},this.props,{onStart:this.onDragStart,onDrag:this.onDrag,onStop:this.onDragStop}),t.cloneElement(h,{className:y,style:C({},h.props.style,a),transform:i}))}}]),r}(t.Component);return oe.displayName="Draggable",oe.propTypes=C({},re.propTypes,{axis:w.oneOf(["both","x","y","none"]),bounds:w.oneOfType([w.shape({left:w.number,right:w.number,top:w.number,bottom:w.number}),w.string,w.oneOf([!1])]),defaultClassName:w.string,defaultClassNameDragging:w.string,defaultClassNameDragged:w.string,defaultPosition:w.shape({x:w.number,y:w.number}),position:w.shape({x:w.number,y:w.number}),className:E,style:E,transform:E}),oe.defaultProps=C({},re.defaultProps,{axis:"both",bounds:!1,defaultClassName:"react-draggable",defaultClassNameDragging:"react-draggable-dragging",defaultClassNameDragged:"react-draggable-dragged",defaultPosition:{x:0,y:0},position:null,scale:1}),oe.default=oe,oe.DraggableCore=re,oe}(n(7),n(0))},function(e,t){e.exports=window.ReactDOM}]);
--------------------------------------------------------------------------------