├── .Rbuildignore ├── .circleci └── config.yml ├── .eslintignore ├── .eslintrc ├── .github ├── CODEOWNERS └── FUNDING.yml ├── .gitignore ├── .npmignore ├── .prettierrc ├── CHANGELOG.md ├── CODE_OF_CONDUCT.md ├── DESCRIPTION ├── LICENSE ├── MANIFEST.in ├── NAMESPACE ├── R ├── daqBooleanSwitch.R ├── daqColorPicker.R ├── daqDarkThemeProvider.R ├── daqGauge.R ├── daqGraduatedBar.R ├── daqIndicator.R ├── daqJoystick.R ├── daqKnob.R ├── daqLEDDisplay.R ├── daqNumericInput.R ├── daqPowerButton.R ├── daqPrecisionInput.R ├── daqSlider.R ├── daqStopButton.R ├── daqTank.R ├── daqThermometer.R ├── daqToggleSwitch.R └── internal.R ├── README.md ├── babel.config.js ├── bin └── generateDocs ├── dash-info.yaml ├── dash_daq ├── BooleanSwitch.py ├── ColorPicker.py ├── DarkThemeProvider.py ├── Gauge.py ├── GraduatedBar.py ├── Indicator.py ├── Joystick.py ├── Knob.py ├── LEDDisplay.py ├── NumericInput.py ├── PowerButton.py ├── PrecisionInput.py ├── Slider.py ├── StopButton.py ├── Tank.py ├── Thermometer.py ├── ToggleSwitch.py ├── __init__.py ├── _imports_.py ├── async-colorpicker.js ├── async-colorpicker.js.map ├── bundle.js ├── bundle.js.map ├── dash_daq.dev.js ├── dash_daq.dev.js.map ├── dash_daq.min.js ├── dash_daq.min.js.map └── package-info.json ├── demo.py ├── demo ├── Demo.react.js ├── index.html └── index.js ├── get_version_info.py ├── inst └── deps │ ├── async-colorpicker.js │ ├── async-colorpicker.js.map │ ├── bundle.js │ ├── bundle.js.map │ ├── dash_daq.dev.js │ ├── dash_daq.dev.js.map │ ├── dash_daq.min.js │ └── dash_daq.min.js.map ├── man ├── daqBooleanSwitch.Rd ├── daqColorPicker.Rd ├── daqDarkThemeProvider.Rd ├── daqGauge.Rd ├── daqGraduatedBar.Rd ├── daqIndicator.Rd ├── daqJoystick.Rd ├── daqKnob.Rd ├── daqLEDDisplay.Rd ├── daqNumericInput.Rd ├── daqPowerButton.Rd ├── daqPrecisionInput.Rd ├── daqSlider.Rd ├── daqStopButton.Rd ├── daqTank.Rd ├── daqThermometer.Rd ├── daqToggleSwitch.Rd └── dashDaq-package.Rd ├── package-lock.json ├── package.json ├── requirements.txt ├── setup.py ├── src ├── components │ ├── BooleanSwitch.react.js │ ├── ColorPicker.react.js │ ├── DarkThemeProvider.react.js │ ├── Gauge.react.js │ ├── GraduatedBar.react.js │ ├── Indicator.react.js │ ├── Joystick.react.js │ ├── Knob.react.js │ ├── LEDDisplay.react.js │ ├── NumericInput.react.js │ ├── PowerButton.react.js │ ├── PrecisionInput.react.js │ ├── Slider.react.js │ ├── StopButton.react.js │ ├── Tank.react.js │ ├── Thermometer.react.js │ ├── ToggleSwitch.react.js │ └── __tests__ │ │ ├── .eslintrc │ │ ├── BooleanSwitch.test.js │ │ ├── ColorPicker.test.js │ │ ├── Gauge.test.js │ │ ├── GraduatedBar.test.js │ │ ├── Indicator.test.js │ │ ├── Knob.test.js │ │ ├── LEDDisplay.test.js │ │ ├── NumericInput.test.js │ │ ├── PowerButton.test.js │ │ ├── PrecisionInput.test.js │ │ ├── Slider.test.js │ │ ├── StopButton.test.js │ │ ├── Tank.test.js │ │ ├── Thermometer.test.js │ │ └── ToggleSwitch.test.js ├── fragments │ ├── ColorPicker.react.js │ └── Slider.react.js ├── helpers │ ├── GaugeSvg.react.js │ ├── KnobSvg.react.js │ ├── LEDDisplaySvg.react.js │ ├── NumericInput.js │ ├── PowerButtonSvg.react.js │ ├── classNameGenerator.js │ ├── colorRanges.js │ ├── logarithm.js │ ├── scale.js │ ├── shared │ │ └── TrackSvg.js │ └── util.js ├── index.js └── styled │ ├── ColorPicker.styled.js │ ├── CurrentValue.styled.js │ ├── Gauge.styled.js │ ├── GraduatedBar.styled.js │ ├── Knob.styled.js │ ├── LEDDisplay.styled.js │ ├── PowerButton.styled.js │ ├── PrecisionInput.styled.js │ ├── Slider.styled.js │ ├── StopButton.styled.js │ ├── Tank.styled.js │ ├── Thermometer.styled.js │ ├── ToggleSwitch.styled.js │ ├── constants.js │ └── shared │ ├── DarkGradient.js │ ├── Indicator.styled.js │ ├── Label.styled.js │ └── LabelContainer.styled.js ├── webpack.config.js └── yarn.lock /.Rbuildignore: -------------------------------------------------------------------------------- 1 | # ignore JS config files/folders 2 | node_modules/ 3 | coverage/ 4 | src/ 5 | lib/ 6 | .babelrc 7 | .builderrc 8 | .eslintrc 9 | .npmignore 10 | .editorconfig 11 | .eslintignore 12 | .prettierrc 13 | .circleci 14 | .github 15 | 16 | # demo folder has special meaning in R 17 | # this should hopefully make it still 18 | # allow for the possibility to make R demos 19 | demo/.*\.js 20 | demo/.*\.html 21 | demo/.*\.css 22 | 23 | # ignore Python files/folders 24 | setup.py 25 | usage.py 26 | setup.py 27 | requirements.txt 28 | MANIFEST.in 29 | CHANGELOG.md 30 | test/ 31 | # CRAN has weird LICENSE requirements 32 | LICENSE.txt 33 | ^.*\.Rproj$ 34 | ^\.Rproj\.user$ 35 | -------------------------------------------------------------------------------- /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | 3 | jobs: 4 | build_and_test_node: 5 | docker: 6 | - image: circleci/python:3.7-stretch-node 7 | auth: 8 | username: dashautomation 9 | password: $DASH_PAT_DOCKERHUB 10 | steps: 11 | - checkout 12 | - run: 13 | name: Check current version of node 14 | command: node -v 15 | - restore_cache: 16 | key: deps1-{{ .Branch }}-{{ checksum "package-lock.json" }} 17 | 18 | - run: 19 | name: Install package.json 20 | command: npm ci 21 | 22 | - save_cache: 23 | key: deps1-{{ .Branch }}-{{ checksum "package-lock.json" }} 24 | paths: 25 | - node_modules 26 | 27 | - run: 28 | name: Install Dash for package build and build package 29 | command: | 30 | python -m venv venv 31 | . venv/bin/activate 32 | pip install --upgrade dash[dev,testing] 33 | 34 | 35 | - run: 36 | name: Run unit tests 37 | command: | 38 | npm run test 39 | 40 | workflows: 41 | version: 2 42 | build: 43 | jobs: 44 | - build_and_test_node 45 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | build/ 2 | coverage/ 3 | dist/ 4 | lib/ 5 | lib/*.js* 6 | node_modules/ 7 | dash_daq/metadata.json 8 | dash_daq/*.js* 9 | inst/deps/*.js* 10 | babel.config.js 11 | webpack.config.js 12 | .npm 13 | vv/ 14 | venv/ 15 | *.pyc 16 | *.egg-info 17 | *.log 18 | .DS_Store 19 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "./node_modules/dash-components-archetype/config/eslint/eslintrc-react.json" 4 | ], 5 | "parser": "babel-eslint", 6 | "plugins": [ 7 | "react", 8 | "import" 9 | ], 10 | "settings": { 11 | "import/extensions": [ 12 | ".css$" 13 | ] 14 | } 15 | } -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | # These owners will be the default owners for everything in 2 | # the repo. Unless a later match takes precedence 3 | * @Marc-Andre-Rivet @shammamah 4 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | custom: https://plotly.com/products/consulting-and-oem/ 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | build/ 2 | coverage/ 3 | dist/ 4 | lib/ 5 | lib/bundle.js* 6 | node_modules/ 7 | dash_daq/metadata.json 8 | dash_daq/bundle.js* 9 | .npm 10 | vv/ 11 | venv/ 12 | *.pyc 13 | *.egg-info 14 | *.log 15 | .DS_Store 16 | .vscode 17 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | .npm 3 | .git/ 4 | vv/ 5 | venv/ 6 | *.pyc 7 | *.log 8 | .DS_Store 9 | 10 | build/ 11 | coverage/ 12 | dist/ 13 | lib/ 14 | lib/bundle.js* 15 | node_modules/ 16 | *.egg-info 17 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true 3 | } 4 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to this project will be documented in this file. 4 | 5 | The format is based on [Keep a 6 | Changelog](http://keepachangelog.com/en/1.0.0/) and this project 7 | adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). 8 | 9 | ## [Unreleased] 10 | ### Added 11 | - [#117](https://github.com/plotly/dash-daq/pull/117) Added `digits` prop to `Gauge` component. 12 | 13 | ## [0.5.0] - 2020-04-27 14 | ### Added 15 | - [#105](https://github.com/plotly/dash-daq/pull/105) Added [persistence](https://dash.plotly.com/persistence) for 16 | components BooleanSwitch, ColorPicker, Knob, NumericInput, PowerButton, PrecisionInput, Slider and ToggleSwitch 17 | 18 | ### Changed 19 | - [#92](https://github.com/plotly/dash-daq/pull/92) Update from React 16.8.6 to 16.13.0 20 | 21 | ## [0.4.0] - 2020-03-04 22 | ### Added 23 | - [#80](https://github.com/plotly/dash-daq/pull/80) Added `theme` prop to `GraduatedBar` component. 24 | 25 | ### Changed 26 | - [#91](https://github.com/plotly/dash-daq/pull/91) Renamed async modules with hyphen `-` instead of tilde `~` 27 | - [#80](https://github.com/plotly/dash-daq/pull/80) Changed class names for components according to BEM conventions. 28 | 29 | ### Fixed 30 | - [#80](https://github.com/plotly/dash-daq/pull/80) Fixed color problems for dark-theme buttons and inputs. 31 | 32 | ## [0.3.3] - 2020-01-23 33 | ### Changed 34 | - [#82](https://github.com/plotly/dash-daq/pull/82) Updated `rc-slider` package and `daq.Slider` styling. 35 | 36 | ## [0.3.2] - 2020-01-22 37 | ### Fixed 38 | - [#84](https://github.com/plotly/dash-daq/pull/84) Fixed JS map not being included in the `js_dist` for the Python package. 39 | 40 | ## [0.3.1] - 2019-11-14 41 | ### Fixed 42 | - [#73](https://github.com/plotly/dash-daq/pull/73) Fix IE11 compatibility issues and ES5 compatibility and validation 43 | 44 | ## [0.3.0] - 2019-11-05 45 | ### Added 46 | - [#70](https://github.com/plotly/dash-daq/pull/70) Async ColorPicker and Slider components 47 | 48 | ## [0.2.2] - 2019-10-04 49 | 50 | ### Fixed 51 | - Fixed ThemeProvider warning by updating `styled-components` to `v4.4.0`. 52 | 53 | ## [0.2.1] - 2019-09-24 54 | 55 | ### Fixed 56 | - Fixed "Cannot read property 'subscribe' of undefined" JavaScript 57 | error. 58 | 59 | ## [0.2.0] - 2019-09-24 60 | 61 | ### Added 62 | - Added `height` and `width` parameters to `daq.Tank` and 63 | `daq.Thermometer`. 64 | 65 | ## [0.1.7] - 2019-07-24 66 | 67 | ### Changed 68 | - Updated library to React 16 for compatibility with `dash-1.0.0`. 69 | 70 | ## [0.1.6] - 2019-07-16 71 | 72 | ### Added 73 | - Added ability for LEDDisplay to handle negative numbers. 74 | 75 | ## [0.1.5] - 2019-05-09 76 | 77 | ### Fixed 78 | - Fixed missing locationSlider entry in Slider.propTypes. 79 | 80 | ### Added 81 | 82 | - Updated package.json with additional metadata for R package 83 | building. 84 | - Added JavaScript bundle and source map to dash_daq subfolder. 85 | - Initial commit of dashDaq R package. 86 | 87 | ## [0.1.4] - 2019-02-18 88 | 89 | ### Fixed 90 | - Fixed init file to include the correct bundle location. 91 | - Fixed NPM package to include bundle, and updated Python package 92 | version accordingly. 93 | 94 | ## [0.1.2] - 2019-02-15 95 | 96 | ### Fixed 97 | - Fixed version to correspond to the correct/published npm version. 98 | 99 | ## [0.1.1] - 2019-02-14 100 | 101 | ### Fixed 102 | - Fixed version to correspond to the correct/published npm version. 103 | 104 | ## [0.1.0] - 2019-01-28 105 | 106 | ### Fixed 107 | - Fixed incompatibility issue with Dash `0.36.0`. 108 | 109 | ### Removed 110 | - Removed unused headers in CHANGELOG. 111 | - Removed all mentioned of `fireEvent` and anything else that used 112 | Dash events (which have been removed). The `n_clicks` and `value` 113 | props should be used instead to determine when something has been 114 | updated. 115 | 116 | ## [0.0.2] - 2018-06-04 117 | 118 | ### Fixed 119 | - Error on Windows when generating tarball. Fixed dependency problems 120 | with import dash_daq. 121 | 122 | ## [0.0.1] - 2018-05-28 123 | 124 | ### Fixed 125 | 126 | - Display error on ColorPicker Light component fixed 127 | - Gauge component error with default values fixed 128 | - Knob component error with JavaScript split method fixed 129 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. 6 | 7 | ## Our Standards 8 | 9 | Examples of behavior that contributes to creating a positive environment include: 10 | 11 | * Using welcoming and inclusive language 12 | * Being respectful of differing viewpoints and experiences 13 | * Gracefully accepting constructive criticism 14 | * Focusing on what is best for the community 15 | * Showing empathy towards other community members 16 | 17 | Examples of unacceptable behavior by participants include: 18 | 19 | * The use of sexualized language or imagery and unwelcome sexual attention or advances 20 | * Trolling, insulting/derogatory comments, and personal or political attacks 21 | * Public or private harassment 22 | * Publishing others' private information, such as a physical or electronic address, without explicit permission 23 | * Other conduct which could reasonably be considered inappropriate in a professional setting 24 | 25 | ## Our Responsibilities 26 | 27 | Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. 28 | 29 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. 30 | 31 | ## Scope 32 | 33 | This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. 34 | 35 | ## Enforcement 36 | 37 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at accounts@plot.ly. All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. 38 | 39 | Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. 40 | 41 | ## Attribution 42 | 43 | This Code of Conduct is adapted from the [Contributor Covenant](http://contributor-covenant.org), version 1.4, available at [http://contributor-covenant.org/version/1/4](http://contributor-covenant.org/version/1/4/), and may also be found online at . 44 | -------------------------------------------------------------------------------- /DESCRIPTION: -------------------------------------------------------------------------------- 1 | Package: dashDaq 2 | Title: Interactive Data Acquisition and Control Components for Dash 3 | Version: 0.5.1 4 | Description: A robust set of controls that make it simpler to integrate data acquisition and controls into your Dash applications. 5 | Depends: R (>= 3.0.2) 6 | Imports: 7 | Suggests: 8 | Authors@R: person("The", "Team", role = c("aut", "cre"), email = "dashdaq@plotly.com") 9 | License: MIT + file LICENSE 10 | URL: https://github.com/plotly/dash-daq 11 | BugReports: https://github.com/plotly/dash-daq/issues 12 | Encoding: UTF-8 13 | LazyData: true 14 | KeepSource: true 15 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019-2024 Plotly Technologies Inc. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include dash_daq/dash_daq.min.js 2 | include dash_daq/dash_daq.min.js.map 3 | include dash_daq/async-*.js 4 | include dash_daq/async-*.js.map 5 | include dash_daq/metadata.json 6 | include dash_daq/package-info.json 7 | include README.md 8 | include LICENSE 9 | -------------------------------------------------------------------------------- /NAMESPACE: -------------------------------------------------------------------------------- 1 | # AUTO GENERATED FILE - DO NOT EDIT 2 | 3 | export(daqBooleanSwitch) 4 | export(daqColorPicker) 5 | export(daqDarkThemeProvider) 6 | export(daqGauge) 7 | export(daqGraduatedBar) 8 | export(daqIndicator) 9 | export(daqJoystick) 10 | export(daqKnob) 11 | export(daqLEDDisplay) 12 | export(daqNumericInput) 13 | export(daqPowerButton) 14 | export(daqPrecisionInput) 15 | export(daqSlider) 16 | export(daqStopButton) 17 | export(daqTank) 18 | export(daqThermometer) 19 | export(daqToggleSwitch) 20 | -------------------------------------------------------------------------------- /R/daqBooleanSwitch.R: -------------------------------------------------------------------------------- 1 | # AUTO GENERATED FILE - DO NOT EDIT 2 | 3 | daqBooleanSwitch <- function(id=NULL, className=NULL, color=NULL, disabled=NULL, label=NULL, labelPosition=NULL, on=NULL, persisted_props=NULL, persistence=NULL, persistence_type=NULL, size=NULL, style=NULL, theme=NULL, vertical=NULL) { 4 | 5 | props <- list(id=id, className=className, color=color, disabled=disabled, label=label, labelPosition=labelPosition, on=on, persisted_props=persisted_props, persistence=persistence, persistence_type=persistence_type, size=size, style=style, theme=theme, vertical=vertical) 6 | if (length(props) > 0) { 7 | props <- props[!vapply(props, is.null, logical(1))] 8 | } 9 | component <- list( 10 | props = props, 11 | type = 'BooleanSwitch', 12 | namespace = 'dash_daq', 13 | propNames = c('id', 'className', 'color', 'disabled', 'label', 'labelPosition', 'on', 'persisted_props', 'persistence', 'persistence_type', 'size', 'style', 'theme', 'vertical'), 14 | package = 'dashDaq' 15 | ) 16 | 17 | structure(component, class = c('dash_component', 'list')) 18 | } 19 | -------------------------------------------------------------------------------- /R/daqColorPicker.R: -------------------------------------------------------------------------------- 1 | # AUTO GENERATED FILE - DO NOT EDIT 2 | 3 | daqColorPicker <- function(id=NULL, className=NULL, disabled=NULL, label=NULL, labelPosition=NULL, persisted_props=NULL, persistence=NULL, persistence_type=NULL, size=NULL, style=NULL, theme=NULL, value=NULL) { 4 | 5 | props <- list(id=id, className=className, disabled=disabled, label=label, labelPosition=labelPosition, persisted_props=persisted_props, persistence=persistence, persistence_type=persistence_type, size=size, style=style, theme=theme, value=value) 6 | if (length(props) > 0) { 7 | props <- props[!vapply(props, is.null, logical(1))] 8 | } 9 | component <- list( 10 | props = props, 11 | type = 'ColorPicker', 12 | namespace = 'dash_daq', 13 | propNames = c('id', 'className', 'disabled', 'label', 'labelPosition', 'persisted_props', 'persistence', 'persistence_type', 'size', 'style', 'theme', 'value'), 14 | package = 'dashDaq' 15 | ) 16 | 17 | structure(component, class = c('dash_component', 'list')) 18 | } 19 | -------------------------------------------------------------------------------- /R/daqDarkThemeProvider.R: -------------------------------------------------------------------------------- 1 | # AUTO GENERATED FILE - DO NOT EDIT 2 | 3 | daqDarkThemeProvider <- function(children=NULL, theme=NULL) { 4 | 5 | props <- list(children=children, theme=theme) 6 | if (length(props) > 0) { 7 | props <- props[!vapply(props, is.null, logical(1))] 8 | } 9 | component <- list( 10 | props = props, 11 | type = 'DarkThemeProvider', 12 | namespace = 'dash_daq', 13 | propNames = c('children', 'theme'), 14 | package = 'dashDaq' 15 | ) 16 | 17 | structure(component, class = c('dash_component', 'list')) 18 | } 19 | -------------------------------------------------------------------------------- /R/daqGauge.R: -------------------------------------------------------------------------------- 1 | # AUTO GENERATED FILE - DO NOT EDIT 2 | 3 | daqGauge <- function(id=NULL, base=NULL, className=NULL, color=NULL, digits=NULL, exceedMessage=NULL, label=NULL, labelPosition=NULL, lagingMessage=NULL, logarithmic=NULL, max=NULL, min=NULL, scale=NULL, showCurrentValue=NULL, size=NULL, style=NULL, textColor=NULL, theme=NULL, units=NULL, value=NULL) { 4 | 5 | props <- list(id=id, base=base, className=className, color=color, digits=digits, exceedMessage=exceedMessage, label=label, labelPosition=labelPosition, lagingMessage=lagingMessage, logarithmic=logarithmic, max=max, min=min, scale=scale, showCurrentValue=showCurrentValue, size=size, style=style, textColor=textColor, theme=theme, units=units, value=value) 6 | if (length(props) > 0) { 7 | props <- props[!vapply(props, is.null, logical(1))] 8 | } 9 | component <- list( 10 | props = props, 11 | type = 'Gauge', 12 | namespace = 'dash_daq', 13 | propNames = c('id', 'base', 'className', 'color', 'digits', 'exceedMessage', 'label', 'labelPosition', 'lagingMessage', 'logarithmic', 'max', 'min', 'scale', 'showCurrentValue', 'size', 'style', 'textColor', 'theme', 'units', 'value'), 14 | package = 'dashDaq' 15 | ) 16 | 17 | structure(component, class = c('dash_component', 'list')) 18 | } 19 | -------------------------------------------------------------------------------- /R/daqGraduatedBar.R: -------------------------------------------------------------------------------- 1 | # AUTO GENERATED FILE - DO NOT EDIT 2 | 3 | daqGraduatedBar <- function(id=NULL, className=NULL, color=NULL, label=NULL, labelPosition=NULL, max=NULL, min=NULL, showCurrentValue=NULL, size=NULL, step=NULL, style=NULL, theme=NULL, value=NULL, vertical=NULL) { 4 | 5 | props <- list(id=id, className=className, color=color, label=label, labelPosition=labelPosition, max=max, min=min, showCurrentValue=showCurrentValue, size=size, step=step, style=style, theme=theme, value=value, vertical=vertical) 6 | if (length(props) > 0) { 7 | props <- props[!vapply(props, is.null, logical(1))] 8 | } 9 | component <- list( 10 | props = props, 11 | type = 'GraduatedBar', 12 | namespace = 'dash_daq', 13 | propNames = c('id', 'className', 'color', 'label', 'labelPosition', 'max', 'min', 'showCurrentValue', 'size', 'step', 'style', 'theme', 'value', 'vertical'), 14 | package = 'dashDaq' 15 | ) 16 | 17 | structure(component, class = c('dash_component', 'list')) 18 | } 19 | -------------------------------------------------------------------------------- /R/daqIndicator.R: -------------------------------------------------------------------------------- 1 | # AUTO GENERATED FILE - DO NOT EDIT 2 | 3 | daqIndicator <- function(id=NULL, className=NULL, color=NULL, height=NULL, label=NULL, labelPosition=NULL, size=NULL, style=NULL, theme=NULL, value=NULL, width=NULL) { 4 | 5 | props <- list(id=id, className=className, color=color, height=height, label=label, labelPosition=labelPosition, size=size, style=style, theme=theme, value=value, width=width) 6 | if (length(props) > 0) { 7 | props <- props[!vapply(props, is.null, logical(1))] 8 | } 9 | component <- list( 10 | props = props, 11 | type = 'Indicator', 12 | namespace = 'dash_daq', 13 | propNames = c('id', 'className', 'color', 'height', 'label', 'labelPosition', 'size', 'style', 'theme', 'value', 'width'), 14 | package = 'dashDaq' 15 | ) 16 | 17 | structure(component, class = c('dash_component', 'list')) 18 | } 19 | -------------------------------------------------------------------------------- /R/daqJoystick.R: -------------------------------------------------------------------------------- 1 | # AUTO GENERATED FILE - DO NOT EDIT 2 | 3 | daqJoystick <- function(id=NULL, angle=NULL, className=NULL, force=NULL, label=NULL, labelPosition=NULL, size=NULL, style=NULL, theme=NULL) { 4 | 5 | props <- list(id=id, angle=angle, className=className, force=force, label=label, labelPosition=labelPosition, size=size, style=style, theme=theme) 6 | if (length(props) > 0) { 7 | props <- props[!vapply(props, is.null, logical(1))] 8 | } 9 | component <- list( 10 | props = props, 11 | type = 'Joystick', 12 | namespace = 'dash_daq', 13 | propNames = c('id', 'angle', 'className', 'force', 'label', 'labelPosition', 'size', 'style', 'theme'), 14 | package = 'dashDaq' 15 | ) 16 | 17 | structure(component, class = c('dash_component', 'list')) 18 | } 19 | -------------------------------------------------------------------------------- /R/daqKnob.R: -------------------------------------------------------------------------------- 1 | # AUTO GENERATED FILE - DO NOT EDIT 2 | 3 | daqKnob <- function(id=NULL, className=NULL, color=NULL, digits=NULL, disabled=NULL, label=NULL, labelPosition=NULL, max=NULL, min=NULL, persisted_props=NULL, persistence=NULL, persistence_type=NULL, scale=NULL, showCurrentValue=NULL, size=NULL, style=NULL, textColor=NULL, theme=NULL, value=NULL) { 4 | 5 | props <- list(id=id, className=className, color=color, digits=digits, disabled=disabled, label=label, labelPosition=labelPosition, max=max, min=min, persisted_props=persisted_props, persistence=persistence, persistence_type=persistence_type, scale=scale, showCurrentValue=showCurrentValue, size=size, style=style, textColor=textColor, theme=theme, value=value) 6 | if (length(props) > 0) { 7 | props <- props[!vapply(props, is.null, logical(1))] 8 | } 9 | component <- list( 10 | props = props, 11 | type = 'Knob', 12 | namespace = 'dash_daq', 13 | propNames = c('id', 'className', 'color', 'digits', 'disabled', 'label', 'labelPosition', 'max', 'min', 'persisted_props', 'persistence', 'persistence_type', 'scale', 'showCurrentValue', 'size', 'style', 'textColor', 'theme', 'value'), 14 | package = 'dashDaq' 15 | ) 16 | 17 | structure(component, class = c('dash_component', 'list')) 18 | } 19 | -------------------------------------------------------------------------------- /R/daqLEDDisplay.R: -------------------------------------------------------------------------------- 1 | # AUTO GENERATED FILE - DO NOT EDIT 2 | 3 | daqLEDDisplay <- function(id=NULL, backgroundColor=NULL, className=NULL, color=NULL, label=NULL, labelPosition=NULL, size=NULL, style=NULL, theme=NULL, value=NULL) { 4 | 5 | props <- list(id=id, backgroundColor=backgroundColor, className=className, color=color, label=label, labelPosition=labelPosition, size=size, style=style, theme=theme, value=value) 6 | if (length(props) > 0) { 7 | props <- props[!vapply(props, is.null, logical(1))] 8 | } 9 | component <- list( 10 | props = props, 11 | type = 'LEDDisplay', 12 | namespace = 'dash_daq', 13 | propNames = c('id', 'backgroundColor', 'className', 'color', 'label', 'labelPosition', 'size', 'style', 'theme', 'value'), 14 | package = 'dashDaq' 15 | ) 16 | 17 | structure(component, class = c('dash_component', 'list')) 18 | } 19 | -------------------------------------------------------------------------------- /R/daqNumericInput.R: -------------------------------------------------------------------------------- 1 | # AUTO GENERATED FILE - DO NOT EDIT 2 | 3 | daqNumericInput <- function(id=NULL, className=NULL, disabled=NULL, label=NULL, labelPosition=NULL, max=NULL, min=NULL, persisted_props=NULL, persistence=NULL, persistence_type=NULL, size=NULL, style=NULL, theme=NULL, value=NULL) { 4 | 5 | props <- list(id=id, className=className, disabled=disabled, label=label, labelPosition=labelPosition, max=max, min=min, persisted_props=persisted_props, persistence=persistence, persistence_type=persistence_type, size=size, style=style, theme=theme, value=value) 6 | if (length(props) > 0) { 7 | props <- props[!vapply(props, is.null, logical(1))] 8 | } 9 | component <- list( 10 | props = props, 11 | type = 'NumericInput', 12 | namespace = 'dash_daq', 13 | propNames = c('id', 'className', 'disabled', 'label', 'labelPosition', 'max', 'min', 'persisted_props', 'persistence', 'persistence_type', 'size', 'style', 'theme', 'value'), 14 | package = 'dashDaq' 15 | ) 16 | 17 | structure(component, class = c('dash_component', 'list')) 18 | } 19 | -------------------------------------------------------------------------------- /R/daqPowerButton.R: -------------------------------------------------------------------------------- 1 | # AUTO GENERATED FILE - DO NOT EDIT 2 | 3 | daqPowerButton <- function(id=NULL, className=NULL, color=NULL, disabled=NULL, label=NULL, labelPosition=NULL, offButtonStyle=NULL, on=NULL, onButtonStyle=NULL, persisted_props=NULL, persistence=NULL, persistence_type=NULL, size=NULL, style=NULL, theme=NULL) { 4 | 5 | props <- list(id=id, className=className, color=color, disabled=disabled, label=label, labelPosition=labelPosition, offButtonStyle=offButtonStyle, on=on, onButtonStyle=onButtonStyle, persisted_props=persisted_props, persistence=persistence, persistence_type=persistence_type, size=size, style=style, theme=theme) 6 | if (length(props) > 0) { 7 | props <- props[!vapply(props, is.null, logical(1))] 8 | } 9 | component <- list( 10 | props = props, 11 | type = 'PowerButton', 12 | namespace = 'dash_daq', 13 | propNames = c('id', 'className', 'color', 'disabled', 'label', 'labelPosition', 'offButtonStyle', 'on', 'onButtonStyle', 'persisted_props', 'persistence', 'persistence_type', 'size', 'style', 'theme'), 14 | package = 'dashDaq' 15 | ) 16 | 17 | structure(component, class = c('dash_component', 'list')) 18 | } 19 | -------------------------------------------------------------------------------- /R/daqPrecisionInput.R: -------------------------------------------------------------------------------- 1 | # AUTO GENERATED FILE - DO NOT EDIT 2 | 3 | daqPrecisionInput <- function(id=NULL, className=NULL, disabled=NULL, label=NULL, labelPosition=NULL, max=NULL, min=NULL, persisted_props=NULL, persistence=NULL, persistence_type=NULL, precision=NULL, size=NULL, style=NULL, theme=NULL, value=NULL) { 4 | 5 | props <- list(id=id, className=className, disabled=disabled, label=label, labelPosition=labelPosition, max=max, min=min, persisted_props=persisted_props, persistence=persistence, persistence_type=persistence_type, precision=precision, size=size, style=style, theme=theme, value=value) 6 | if (length(props) > 0) { 7 | props <- props[!vapply(props, is.null, logical(1))] 8 | } 9 | component <- list( 10 | props = props, 11 | type = 'PrecisionInput', 12 | namespace = 'dash_daq', 13 | propNames = c('id', 'className', 'disabled', 'label', 'labelPosition', 'max', 'min', 'persisted_props', 'persistence', 'persistence_type', 'precision', 'size', 'style', 'theme', 'value'), 14 | package = 'dashDaq' 15 | ) 16 | 17 | structure(component, class = c('dash_component', 'list')) 18 | } 19 | -------------------------------------------------------------------------------- /R/daqSlider.R: -------------------------------------------------------------------------------- 1 | # AUTO GENERATED FILE - DO NOT EDIT 2 | 3 | daqSlider <- function(id=NULL, className=NULL, color=NULL, disabled=NULL, dots=NULL, fullSize=NULL, handleLabel=NULL, included=NULL, labelPosition=NULL, marks=NULL, max=NULL, min=NULL, persisted_props=NULL, persistence=NULL, persistence_type=NULL, size=NULL, step=NULL, style=NULL, targets=NULL, theme=NULL, updatemode=NULL, value=NULL, vertical=NULL) { 4 | 5 | props <- list(id=id, className=className, color=color, disabled=disabled, dots=dots, fullSize=fullSize, handleLabel=handleLabel, included=included, labelPosition=labelPosition, marks=marks, max=max, min=min, persisted_props=persisted_props, persistence=persistence, persistence_type=persistence_type, size=size, step=step, style=style, targets=targets, theme=theme, updatemode=updatemode, value=value, vertical=vertical) 6 | if (length(props) > 0) { 7 | props <- props[!vapply(props, is.null, logical(1))] 8 | } 9 | component <- list( 10 | props = props, 11 | type = 'Slider', 12 | namespace = 'dash_daq', 13 | propNames = c('id', 'className', 'color', 'disabled', 'dots', 'fullSize', 'handleLabel', 'included', 'labelPosition', 'marks', 'max', 'min', 'persisted_props', 'persistence', 'persistence_type', 'size', 'step', 'style', 'targets', 'theme', 'updatemode', 'value', 'vertical'), 14 | package = 'dashDaq' 15 | ) 16 | 17 | structure(component, class = c('dash_component', 'list')) 18 | } 19 | -------------------------------------------------------------------------------- /R/daqStopButton.R: -------------------------------------------------------------------------------- 1 | # AUTO GENERATED FILE - DO NOT EDIT 2 | 3 | daqStopButton <- function(children=NULL, id=NULL, buttonText=NULL, className=NULL, disabled=NULL, label=NULL, labelPosition=NULL, n_clicks=NULL, size=NULL, style=NULL, theme=NULL) { 4 | 5 | props <- list(children=children, id=id, buttonText=buttonText, className=className, disabled=disabled, label=label, labelPosition=labelPosition, n_clicks=n_clicks, size=size, style=style, theme=theme) 6 | if (length(props) > 0) { 7 | props <- props[!vapply(props, is.null, logical(1))] 8 | } 9 | component <- list( 10 | props = props, 11 | type = 'StopButton', 12 | namespace = 'dash_daq', 13 | propNames = c('children', 'id', 'buttonText', 'className', 'disabled', 'label', 'labelPosition', 'n_clicks', 'size', 'style', 'theme'), 14 | package = 'dashDaq' 15 | ) 16 | 17 | structure(component, class = c('dash_component', 'list')) 18 | } 19 | -------------------------------------------------------------------------------- /R/daqTank.R: -------------------------------------------------------------------------------- 1 | # AUTO GENERATED FILE - DO NOT EDIT 2 | 3 | daqTank <- function(id=NULL, base=NULL, className=NULL, color=NULL, currentValueStyle=NULL, exceedMessage=NULL, height=NULL, label=NULL, labelPosition=NULL, lagingMessage=NULL, logarithmic=NULL, max=NULL, min=NULL, scale=NULL, showCurrentValue=NULL, style=NULL, textColor=NULL, theme=NULL, units=NULL, value=NULL, width=NULL) { 4 | 5 | props <- list(id=id, base=base, className=className, color=color, currentValueStyle=currentValueStyle, exceedMessage=exceedMessage, height=height, label=label, labelPosition=labelPosition, lagingMessage=lagingMessage, logarithmic=logarithmic, max=max, min=min, scale=scale, showCurrentValue=showCurrentValue, style=style, textColor=textColor, theme=theme, units=units, value=value, width=width) 6 | if (length(props) > 0) { 7 | props <- props[!vapply(props, is.null, logical(1))] 8 | } 9 | component <- list( 10 | props = props, 11 | type = 'Tank', 12 | namespace = 'dash_daq', 13 | propNames = c('id', 'base', 'className', 'color', 'currentValueStyle', 'exceedMessage', 'height', 'label', 'labelPosition', 'lagingMessage', 'logarithmic', 'max', 'min', 'scale', 'showCurrentValue', 'style', 'textColor', 'theme', 'units', 'value', 'width'), 14 | package = 'dashDaq' 15 | ) 16 | 17 | structure(component, class = c('dash_component', 'list')) 18 | } 19 | -------------------------------------------------------------------------------- /R/daqThermometer.R: -------------------------------------------------------------------------------- 1 | # AUTO GENERATED FILE - DO NOT EDIT 2 | 3 | daqThermometer <- function(id=NULL, base=NULL, className=NULL, color=NULL, height=NULL, label=NULL, labelPosition=NULL, logarithmic=NULL, max=NULL, min=NULL, scale=NULL, showCurrentValue=NULL, style=NULL, theme=NULL, units=NULL, value=NULL, width=NULL) { 4 | 5 | props <- list(id=id, base=base, className=className, color=color, height=height, label=label, labelPosition=labelPosition, logarithmic=logarithmic, max=max, min=min, scale=scale, showCurrentValue=showCurrentValue, style=style, theme=theme, units=units, value=value, width=width) 6 | if (length(props) > 0) { 7 | props <- props[!vapply(props, is.null, logical(1))] 8 | } 9 | component <- list( 10 | props = props, 11 | type = 'Thermometer', 12 | namespace = 'dash_daq', 13 | propNames = c('id', 'base', 'className', 'color', 'height', 'label', 'labelPosition', 'logarithmic', 'max', 'min', 'scale', 'showCurrentValue', 'style', 'theme', 'units', 'value', 'width'), 14 | package = 'dashDaq' 15 | ) 16 | 17 | structure(component, class = c('dash_component', 'list')) 18 | } 19 | -------------------------------------------------------------------------------- /R/daqToggleSwitch.R: -------------------------------------------------------------------------------- 1 | # AUTO GENERATED FILE - DO NOT EDIT 2 | 3 | daqToggleSwitch <- function(id=NULL, className=NULL, color=NULL, disabled=NULL, label=NULL, labelPosition=NULL, persisted_props=NULL, persistence=NULL, persistence_type=NULL, size=NULL, style=NULL, theme=NULL, value=NULL, vertical=NULL) { 4 | 5 | props <- list(id=id, className=className, color=color, disabled=disabled, label=label, labelPosition=labelPosition, persisted_props=persisted_props, persistence=persistence, persistence_type=persistence_type, size=size, style=style, theme=theme, value=value, vertical=vertical) 6 | if (length(props) > 0) { 7 | props <- props[!vapply(props, is.null, logical(1))] 8 | } 9 | component <- list( 10 | props = props, 11 | type = 'ToggleSwitch', 12 | namespace = 'dash_daq', 13 | propNames = c('id', 'className', 'color', 'disabled', 'label', 'labelPosition', 'persisted_props', 'persistence', 'persistence_type', 'size', 'style', 'theme', 'value', 'vertical'), 14 | package = 'dashDaq' 15 | ) 16 | 17 | structure(component, class = c('dash_component', 'list')) 18 | } 19 | -------------------------------------------------------------------------------- /R/internal.R: -------------------------------------------------------------------------------- 1 | .dashDaq_js_metadata <- function() { 2 | deps_metadata <- list(`dash_daq` = structure(list(name = "dash_daq", 3 | version = "0.5.1", src = list(href = NULL, 4 | file = "deps"), meta = NULL, 5 | script = 'async-colorpicker.js', 6 | stylesheet = NULL, head = NULL, attachment = NULL, package = "dashDaq", 7 | all_files = FALSE, async = TRUE), class = "html_dependency"), 8 | `dash_daq` = structure(list(name = "dash_daq", 9 | version = "0.5.1", src = list(href = NULL, 10 | file = "deps"), meta = NULL, 11 | script = 'async-slider.js', 12 | stylesheet = NULL, head = NULL, attachment = NULL, package = "dashDaq", 13 | all_files = FALSE, async = TRUE), class = "html_dependency"), 14 | `dash_daq` = structure(list(name = "dash_daq", 15 | version = "0.5.1", src = list(href = NULL, 16 | file = "deps"), meta = NULL, 17 | script = 'async-colorpicker.js.map', 18 | stylesheet = NULL, head = NULL, attachment = NULL, package = "dashDaq", 19 | all_files = FALSE, dynamic = TRUE), class = "html_dependency"), 20 | `dash_daq` = structure(list(name = "dash_daq", 21 | version = "0.5.1", src = list(href = NULL, 22 | file = "deps"), meta = NULL, 23 | script = 'async-slider.js.map', 24 | stylesheet = NULL, head = NULL, attachment = NULL, package = "dashDaq", 25 | all_files = FALSE, dynamic = TRUE), class = "html_dependency"), 26 | `dash_daq` = structure(list(name = "dash_daq", 27 | version = "0.5.1", src = list(href = NULL, 28 | file = "deps"), meta = NULL, 29 | script = 'dash_daq.min.js', 30 | stylesheet = NULL, head = NULL, attachment = NULL, package = "dashDaq", 31 | all_files = FALSE), class = "html_dependency"), 32 | `dash_daq` = structure(list(name = "dash_daq", 33 | version = "0.5.1", src = list(href = NULL, 34 | file = "deps"), meta = NULL, 35 | script = 'dash_daq.min.js.map', 36 | stylesheet = NULL, head = NULL, attachment = NULL, package = "dashDaq", 37 | all_files = FALSE, dynamic = TRUE), class = "html_dependency")) 38 | return(deps_metadata) 39 | } 40 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # dash_daq 2 | 3 | DAQ components for Dash. 4 | 5 | Docs: https://dash.plotly.com/dash-daq 6 | 7 |
8 | 9 | Maintained by Plotly 10 | 11 |
12 | 13 | 14 | ## Installation 15 | 16 | `pip install dash_daq` 17 | 18 | (Or for Python 3, `pip3 install dash_daq`) 19 | 20 | ## Getting started for contributors 21 | 22 | The source code and all the subsequent changes should be done inside `src` folder/directory. 23 | 24 | Create a python virtual environment and activate it. inside that virtual enviornment 25 | 26 | ```sh 27 | pip install dash 28 | pip install pyyaml 29 | ``` 30 | 31 | This will install necessary build tools for building and testing library. 32 | 33 | ```sh 34 | # Clone this repository 35 | git clone https://github.com/plotly/dash-daq.git 36 | 37 | # Install dependencies 38 | $ npm install --also=dev 39 | 40 | # Watch source for changes and build to `lib/` 41 | $ npm start 42 | ``` 43 | 44 | ## Documentation 45 | 46 | Component API documentation can be found at https://dash.plotly.com/dash-daq 47 | 48 | ## Development 49 | 50 | ### Demo server 51 | 52 | You can start up a demo development server to see a demo of the rendered 53 | components: 54 | 55 | ```sh 56 | $ npm run dash-demo 57 | ``` 58 | 59 | You have to maintain the list of components in `demo/Demo.react.js`. 60 | 61 | ### Code quality and tests 62 | 63 | #### To run lint and unit tests: 64 | 65 | ```sh 66 | $ npm run test 67 | ``` 68 | 69 | ### Testing your components in Dash 70 | 71 | 1. Build development bundle to `lib/` 72 | 73 | ```sh 74 | $ npm run start 75 | ``` 76 | 77 | 2. Install module locally (after every change) in virtual environment 78 | 79 | ```sh 80 | # Generate metadata, and install the daq pacakage locally for testing 81 | 82 | $ npm run install-local 83 | ``` 84 | 85 | 3. Run the Dash demo 86 | 87 | ```sh 88 | $ npm run dash-demo 89 | ``` 90 | 91 | ## Installing python package locally 92 | 93 | Before publishing to PyPi, you can test installing the module locally: 94 | 95 | ```sh 96 | # Install in `site-packages` on your machine 97 | $ yarn run install-local 98 | ``` 99 | 100 | ## Uninstalling python package locally 101 | 102 | ```sh 103 | $ yarn run uninstall-local 104 | ``` 105 | 106 | ## Producing a new release as a tarball 107 | 108 | ```sh 109 | vim dash_daq/version.py # and increase it to X.X.X 110 | rm -rf node_modules dist build lib 111 | yarn install 112 | yarn build-tarball 113 | ls dist/dash_daq-X.X.X.tar.gz # this is your tarball 114 | ``` 115 | 116 | ## Demo applications 117 | 118 | - Dash Daq HP Multimeter - [http://dash-gallery.plotly.host/dash-daq-hp-multimeter](http://dash-gallery.plotly.host/dash-daq-hp-multimeter) 119 | - Dash Daq IV Tracer - [http://dash-gallery.plotly.host/dash-daq-iv-tracer](http://dash-gallery.plotly.host/dash-daq-iv-tracer) 120 | - Dash Daq Pressure Gauge KJL - [http://dash-gallery.plotly.host/dash-daq-pressure-gauge-kjl](http://dash-gallery.plotly.host/dash-daq-pressure-gauge-kjl) 121 | - Dash Daq Pressure Gauge Pfeiffer - [https://dash-gallery.plotly.host/dash-daq-pressure-gauge-pv](https://dash-gallery.plotly.host/dash-daq-pressure-gauge-pv) 122 | - Dash Daq Sparki - [http://dash-gallery.plotly.host/dash-daq-sparki](http://dash-gallery.plotly.host/dash-daq-sparki) 123 | - Dash Daq Stepper Motor - [http://dash-gallery.plotly.host/dash-daq-stepper-motor](http://dash-gallery.plotly.host/dash-daq-stepper-motor) 124 | - Dash Tektronix 350 - [http://dash-gallery.plotly.host/dash-daq-tektronix350](http://dash-gallery.plotly.host/dash-daq-tektronix350) 125 | - Dash Ocean Optics - [http://dash-gallery.plotly.host/dash-ocean-optics](http://dash-gallery.plotly.host/dash-ocean-optics) 126 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | '@babel/preset-env', 4 | '@babel/preset-react' 5 | ], 6 | plugins: [ 7 | '@babel/plugin-syntax-dynamic-import' 8 | ] 9 | } -------------------------------------------------------------------------------- /bin/generateDocs: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | const path = require('path'); 4 | const fs = require('fs-extra'); 5 | const chalk = require('chalk'); 6 | const reactDocgen = require('react-docgen'); 7 | const ReactDocGenMarkdownRenderer = require('react-docgen-markdown-renderer'); 8 | 9 | const componentDir = path.join(__dirname, '..', 'src', 'components'); 10 | const documentationDir = path.join(__dirname, '..', 'docs'); 11 | 12 | const componentDocTemplate = ` 13 | ## {{componentName}} 14 | 15 | {{#if srcLink }}Component file: [\`{{srcLink}}\`]({{srcLink}}){{/if}} 16 | 17 | {{#if description}}{{{description}}}{{/if}} 18 | 19 | prop | type | default | description 20 | ---- | :----: | :-------: | ----------- 21 | {{#each props}} 22 | **{{@key}}** | \`{{> (typePartial this) this}}\` | {{#if this.defaultValue}}\`{{{this.defaultValue}}}\`{{/if}} | {{#if this.description}}{{{this.description}}}{{/if}} 23 | {{/each}} 24 | `; 25 | 26 | const renderer = new ReactDocGenMarkdownRenderer({ template: componentDocTemplate }); 27 | 28 | genDocumention() 29 | .then(() => console.log(chalk.green('Documentation successfully generated.'))) 30 | .catch(console.error); 31 | 32 | 33 | // helper 34 | async function genDocumention () { 35 | const componentFilenames = fs.readdirSync(componentDir).filter((filename) => filename.includes('.js')); 36 | 37 | await genComponentDocs(componentFilenames); 38 | await genIndexDoc(componentFilenames); 39 | } 40 | 41 | async function genComponentDocs (componentFilenames) { 42 | 43 | const promises = componentFilenames.map((componentFilename) => { 44 | const docFilename = getDocFilename(componentFilename); 45 | const componentPath = path.join(componentDir, componentFilename); 46 | const docPath = path.join(documentationDir, docFilename) 47 | 48 | return documentComponent(componentPath, docPath); 49 | }); 50 | 51 | return Promise.all(promises); 52 | } 53 | 54 | async function genIndexDoc (componentFilenames) { 55 | const indexDocPath = path.join(documentationDir, 'README.md') 56 | let content = ''; 57 | 58 | content += '## Component API Documentation\n\n'; 59 | 60 | componentFilenames.forEach((filename) => { 61 | const componentName = getComponentName(filename); 62 | const docFilename = getDocFilename(filename); 63 | 64 | content += `\n - [${componentName}](/docs/${docFilename})\n`; 65 | }) 66 | 67 | return fs.writeFile(indexDocPath, content); 68 | } 69 | 70 | async function documentComponent (componentPath, docPath) { 71 | const componentName = getComponentName(componentPath); 72 | const fileContent = await fs.readFile(componentPath); 73 | 74 | const doc = reactDocgen.parse(fileContent); 75 | const markdown = renderer.render(componentPath, doc, []) 76 | .split('src/components').join('/src/components') 77 | 78 | return fs.writeFile(docPath, markdown); 79 | } 80 | 81 | 82 | function getDocFilename (componentPath) { 83 | return `${path.basename(componentPath).split('.').shift()}.md`; 84 | } 85 | 86 | function getComponentName (componentPath) { 87 | return path.basename(componentPath).split('.').shift(); 88 | } 89 | -------------------------------------------------------------------------------- /dash-info.yaml: -------------------------------------------------------------------------------- 1 | pkg_help_description: >- 2 | A robust set of controls that make it simpler to integrate data acquisition and controls into your Dash applications. 3 | pkg_help_title: >- 4 | Interactive Data Acquisition and Control Components for Dash 5 | -------------------------------------------------------------------------------- /dash_daq/BooleanSwitch.py: -------------------------------------------------------------------------------- 1 | # AUTO GENERATED FILE - DO NOT EDIT 2 | 3 | from dash.development.base_component import Component, _explicitize_args 4 | 5 | 6 | class BooleanSwitch(Component): 7 | """A BooleanSwitch component. 8 | A switch component that toggles 9 | between on and off. 10 | 11 | Keyword arguments: 12 | 13 | - id (string; optional): 14 | The ID used to identify this component in Dash callbacks. 15 | 16 | - className (string; optional): 17 | Class to apply to the root component element. 18 | 19 | - color (string; optional): 20 | Color to highlight active switch background. 21 | 22 | - disabled (boolean; optional): 23 | If True, switch cannot be clicked. 24 | 25 | - label (dict; optional): 26 | Description to be displayed alongside the control. To control 27 | styling, pass an object with label and style properties. 28 | 29 | `label` is a string | dict with keys: 30 | 31 | - label (string; optional) 32 | 33 | - style (dict; optional) 34 | 35 | - labelPosition (a value equal to: 'top', 'bottom'; default 'top'): 36 | Where the component label is positioned. 37 | 38 | - on (boolean; default False): 39 | Whether or not the switch is on. 40 | 41 | - persisted_props (list of a value equal to: 'on's; default ['on']): 42 | Properties whose user interactions will persist after refreshing 43 | the component or the page. Since only `on` is allowed this prop 44 | can normally be ignored. 45 | 46 | - persistence (boolean | string | number; optional): 47 | Used to allow user interactions in this component to be persisted 48 | when the component - or the page - is refreshed. If `persisted` is 49 | truthy and hasn't changed from its previous value, a `value` that 50 | the user has changed while using the app will keep that change, as 51 | long as the new `value` also matches what was given originally. 52 | Used in conjunction with `persistence_type`. 53 | 54 | - persistence_type (a value equal to: 'local', 'session', 'memory'; default 'local'): 55 | Where persisted user changes will be stored: memory: only kept in 56 | memory, reset on page refresh. local: window.localStorage, data is 57 | kept after the browser quit. session: window.sessionStorage, data 58 | is cleared once the browser quit. 59 | 60 | - size (number; optional): 61 | size of the switch. 62 | 63 | - style (dict; optional): 64 | Style to apply to the root object. 65 | 66 | - theme (dict; default light): 67 | Theme configuration to be set by a ThemeProvider. 68 | 69 | - vertical (boolean; default False): 70 | If True, switch will be vertical instead of horizontal.""" 71 | @_explicitize_args 72 | def __init__(self, id=Component.UNDEFINED, on=Component.UNDEFINED, color=Component.UNDEFINED, vertical=Component.UNDEFINED, disabled=Component.UNDEFINED, theme=Component.UNDEFINED, label=Component.UNDEFINED, labelPosition=Component.UNDEFINED, className=Component.UNDEFINED, style=Component.UNDEFINED, persistence=Component.UNDEFINED, persisted_props=Component.UNDEFINED, persistence_type=Component.UNDEFINED, size=Component.UNDEFINED, **kwargs): 73 | self._prop_names = ['id', 'className', 'color', 'disabled', 'label', 'labelPosition', 'on', 'persisted_props', 'persistence', 'persistence_type', 'size', 'style', 'theme', 'vertical'] 74 | self._type = 'BooleanSwitch' 75 | self._namespace = 'dash_daq' 76 | self._valid_wildcard_attributes = [] 77 | self.available_properties = ['id', 'className', 'color', 'disabled', 'label', 'labelPosition', 'on', 'persisted_props', 'persistence', 'persistence_type', 'size', 'style', 'theme', 'vertical'] 78 | self.available_wildcard_properties = [] 79 | _explicit_args = kwargs.pop('_explicit_args') 80 | _locals = locals() 81 | _locals.update(kwargs) # For wildcard attrs 82 | args = {k: _locals[k] for k in _explicit_args if k != 'children'} 83 | for k in []: 84 | if k not in args: 85 | raise TypeError( 86 | 'Required argument `' + k + '` was not specified.') 87 | super(BooleanSwitch, self).__init__(**args) 88 | -------------------------------------------------------------------------------- /dash_daq/ColorPicker.py: -------------------------------------------------------------------------------- 1 | # AUTO GENERATED FILE - DO NOT EDIT 2 | 3 | from dash.development.base_component import Component, _explicitize_args 4 | 5 | 6 | class ColorPicker(Component): 7 | """A ColorPicker component. 8 | A color picker. 9 | 10 | Keyword arguments: 11 | 12 | - id (string; optional): 13 | The ID used to identify the color picker in Dash callbacks. 14 | 15 | - className (string; optional): 16 | Class to apply to the root component element. 17 | 18 | - disabled (boolean; optional): 19 | If True, color cannot be picked. 20 | 21 | - label (dict; optional): 22 | Description to be displayed alongside the control. To control 23 | styling, pass an object with label and style properties. 24 | 25 | `label` is a string | dict with keys: 26 | 27 | - label (string; optional) 28 | 29 | - style (dict; optional) 30 | 31 | - labelPosition (a value equal to: 'top', 'bottom'; default 'top'): 32 | Where the indicator label is positioned. 33 | 34 | - persisted_props (list of a value equal to: 'value's; default ['value']): 35 | Properties whose user interactions will persist after refreshing 36 | the component or the page. Since only `value` is allowed this prop 37 | can normally be ignored. 38 | 39 | - persistence (boolean | string | number; optional): 40 | Used to allow user interactions in this component to be persisted 41 | when the component - or the page - is refreshed. If `persisted` is 42 | truthy and hasn't changed from its previous value, a `value` that 43 | the user has changed while using the app will keep that change, as 44 | long as the new `value` also matches what was given originally. 45 | Used in conjunction with `persistence_type`. 46 | 47 | - persistence_type (a value equal to: 'local', 'session', 'memory'; default 'local'): 48 | Where persisted user changes will be stored: memory: only kept in 49 | memory, reset on page refresh. local: window.localStorage, data is 50 | kept after the browser quit. session: window.sessionStorage, data 51 | is cleared once the browser quit. 52 | 53 | - size (number; default 225): 54 | Size (width) of the component in pixels. 55 | 56 | - style (dict; optional): 57 | Style to apply to the root component element. 58 | 59 | - theme (dict; default light): 60 | Theme configuration to be set by a ThemeProvider. 61 | 62 | - value (dict; optional): 63 | Color value of the picker. 64 | 65 | `value` is a dict with keys: 66 | 67 | - hex (string; optional): 68 | Hex string. 69 | 70 | - rbg (dict; optional): 71 | RGB/RGBA object. 72 | 73 | `rbg` is a dict with keys: 74 | 75 | - a (number; optional) 76 | 77 | - b (number; optional) 78 | 79 | - g (number; optional) 80 | 81 | - r (number; optional)""" 82 | @_explicitize_args 83 | def __init__(self, id=Component.UNDEFINED, value=Component.UNDEFINED, disabled=Component.UNDEFINED, size=Component.UNDEFINED, theme=Component.UNDEFINED, label=Component.UNDEFINED, labelPosition=Component.UNDEFINED, className=Component.UNDEFINED, style=Component.UNDEFINED, persistence=Component.UNDEFINED, persisted_props=Component.UNDEFINED, persistence_type=Component.UNDEFINED, **kwargs): 84 | self._prop_names = ['id', 'className', 'disabled', 'label', 'labelPosition', 'persisted_props', 'persistence', 'persistence_type', 'size', 'style', 'theme', 'value'] 85 | self._type = 'ColorPicker' 86 | self._namespace = 'dash_daq' 87 | self._valid_wildcard_attributes = [] 88 | self.available_properties = ['id', 'className', 'disabled', 'label', 'labelPosition', 'persisted_props', 'persistence', 'persistence_type', 'size', 'style', 'theme', 'value'] 89 | self.available_wildcard_properties = [] 90 | _explicit_args = kwargs.pop('_explicit_args') 91 | _locals = locals() 92 | _locals.update(kwargs) # For wildcard attrs 93 | args = {k: _locals[k] for k in _explicit_args if k != 'children'} 94 | for k in []: 95 | if k not in args: 96 | raise TypeError( 97 | 'Required argument `' + k + '` was not specified.') 98 | super(ColorPicker, self).__init__(**args) 99 | -------------------------------------------------------------------------------- /dash_daq/DarkThemeProvider.py: -------------------------------------------------------------------------------- 1 | # AUTO GENERATED FILE - DO NOT EDIT 2 | 3 | from dash.development.base_component import Component, _explicitize_args 4 | 5 | 6 | class DarkThemeProvider(Component): 7 | """A DarkThemeProvider component. 8 | DarkThemeProvider is a component that is placed at the root of 9 | the component tree to make all components match the dark theme 10 | 11 | Keyword arguments: 12 | 13 | - children (list of a list of or a singular dash component, string or numbers | a list of or a singular dash component, string or number; optional): 14 | The children of this component. 15 | 16 | - theme (dict; optional): 17 | Theme object to override with a custom theme. 18 | 19 | `theme` is a dict with keys: 20 | 21 | - dark (boolean; optional): 22 | True for Dark mode, False for Light. 23 | 24 | - detail (string; optional): 25 | Color used for UI details, like borders. 26 | 27 | - primary (string; optional): 28 | Highlight color. 29 | 30 | - secondary (string; optional): 31 | Supporting color.""" 32 | @_explicitize_args 33 | def __init__(self, children=None, theme=Component.UNDEFINED, **kwargs): 34 | self._prop_names = ['children', 'theme'] 35 | self._type = 'DarkThemeProvider' 36 | self._namespace = 'dash_daq' 37 | self._valid_wildcard_attributes = [] 38 | self.available_properties = ['children', 'theme'] 39 | self.available_wildcard_properties = [] 40 | _explicit_args = kwargs.pop('_explicit_args') 41 | _locals = locals() 42 | _locals.update(kwargs) # For wildcard attrs 43 | args = {k: _locals[k] for k in _explicit_args if k != 'children'} 44 | for k in []: 45 | if k not in args: 46 | raise TypeError( 47 | 'Required argument `' + k + '` was not specified.') 48 | super(DarkThemeProvider, self).__init__(children=children, **args) 49 | -------------------------------------------------------------------------------- /dash_daq/GraduatedBar.py: -------------------------------------------------------------------------------- 1 | # AUTO GENERATED FILE - DO NOT EDIT 2 | 3 | from dash.development.base_component import Component, _explicitize_args 4 | 5 | 6 | class GraduatedBar(Component): 7 | """A GraduatedBar component. 8 | A graduated bar component that displays 9 | a value within some range as a 10 | percentage. 11 | 12 | Keyword arguments: 13 | 14 | - id (string; optional): 15 | The ID used to identify this compnent in Dash callbacks. 16 | 17 | - className (string; optional): 18 | Class to apply to the root component element. 19 | 20 | - color (dict; default light.primary): 21 | Color configuration for the graduated bar's progress blocks. 22 | 23 | `color` is a string | dict with keys: 24 | 25 | - default (string; optional): 26 | Fallback color to use when color.ranges has gaps. 27 | 28 | - gradient (boolean; optional): 29 | Display ranges as a gradient between given colors. Requires 30 | color.ranges to be contiguous along the entirety of the 31 | graduated bar's range of values. 32 | 33 | - ranges (dict; optional): 34 | Define multiple color ranges on the graduated bar's track. The 35 | key determines the color of the range and the value is the 36 | start,end of the range itself. 37 | 38 | `ranges` is a dict with keys: 39 | 40 | - color (list of numbers; optional) 41 | 42 | - label (dict; optional): 43 | Description to be displayed alongside the control. To control 44 | styling, pass an object with label and style properties. 45 | 46 | `label` is a string | dict with keys: 47 | 48 | - label (string; optional) 49 | 50 | - style (dict; optional) 51 | 52 | - labelPosition (a value equal to: 'top', 'bottom'; default 'top'): 53 | Where the component label is positioned. 54 | 55 | - max (number; default 10): 56 | The maximum value of the graduated bar. 57 | 58 | - min (number; default 0): 59 | The minimum value of the graduated bar. 60 | 61 | - showCurrentValue (boolean; optional): 62 | If True, the current percentage of the bar will be displayed. 63 | 64 | - size (number; default 250): 65 | The size (length) of the graduated bar in pixels. 66 | 67 | - step (number; default 0.5): 68 | Value by which progress blocks appear. 69 | 70 | - style (dict; optional): 71 | Style to apply to the root component element. 72 | 73 | - theme (dict; default light): 74 | Theme configuration to be set by a ThemeProvider. 75 | 76 | - value (number; optional): 77 | The value of the graduated bar. 78 | 79 | - vertical (boolean; optional): 80 | If True, will display bar vertically instead of horizontally.""" 81 | @_explicitize_args 82 | def __init__(self, id=Component.UNDEFINED, value=Component.UNDEFINED, color=Component.UNDEFINED, size=Component.UNDEFINED, vertical=Component.UNDEFINED, min=Component.UNDEFINED, max=Component.UNDEFINED, step=Component.UNDEFINED, showCurrentValue=Component.UNDEFINED, theme=Component.UNDEFINED, label=Component.UNDEFINED, labelPosition=Component.UNDEFINED, className=Component.UNDEFINED, style=Component.UNDEFINED, **kwargs): 83 | self._prop_names = ['id', 'className', 'color', 'label', 'labelPosition', 'max', 'min', 'showCurrentValue', 'size', 'step', 'style', 'theme', 'value', 'vertical'] 84 | self._type = 'GraduatedBar' 85 | self._namespace = 'dash_daq' 86 | self._valid_wildcard_attributes = [] 87 | self.available_properties = ['id', 'className', 'color', 'label', 'labelPosition', 'max', 'min', 'showCurrentValue', 'size', 'step', 'style', 'theme', 'value', 'vertical'] 88 | self.available_wildcard_properties = [] 89 | _explicit_args = kwargs.pop('_explicit_args') 90 | _locals = locals() 91 | _locals.update(kwargs) # For wildcard attrs 92 | args = {k: _locals[k] for k in _explicit_args if k != 'children'} 93 | for k in []: 94 | if k not in args: 95 | raise TypeError( 96 | 'Required argument `' + k + '` was not specified.') 97 | super(GraduatedBar, self).__init__(**args) 98 | -------------------------------------------------------------------------------- /dash_daq/Indicator.py: -------------------------------------------------------------------------------- 1 | # AUTO GENERATED FILE - DO NOT EDIT 2 | 3 | from dash.development.base_component import Component, _explicitize_args 4 | 5 | 6 | class Indicator(Component): 7 | """An Indicator component. 8 | A boolean indicator LED. 9 | 10 | Keyword arguments: 11 | 12 | - id (string; optional): 13 | The ID used to identify the indicator in Dash callbacks. 14 | 15 | - className (string; optional): 16 | Class to apply to the root component element. 17 | 18 | - color (string; default colors.DARKER_PRIMARY): 19 | Color of the indicator. 20 | 21 | - height (number; optional): 22 | Height of the component. Set both width and height for a 23 | rectangular indicator. 24 | 25 | - label (dict; optional): 26 | Description to be displayed alongside the control. To control 27 | styling, pass an object with label and style properties. 28 | 29 | `label` is a string | dict with keys: 30 | 31 | - label (string; optional) 32 | 33 | - style (dict; optional) 34 | 35 | - labelPosition (a value equal to: 'top', 'bottom', 'right', 'left'; default 'top'): 36 | Where the indicator label is positioned. 37 | 38 | - size (number; default 15): 39 | Size of the component. Either use this or width and height. 40 | 41 | - style (dict; optional): 42 | Style to apply to the root component element. 43 | 44 | - theme (dict; default light): 45 | Theme configuration to be set by a ThemeProvider. 46 | 47 | - value (boolean; optional): 48 | If True, indicator is illuminated. 49 | 50 | - width (number; optional): 51 | Width of the component. Set both width and height for a 52 | rectangular indicator.""" 53 | @_explicitize_args 54 | def __init__(self, id=Component.UNDEFINED, value=Component.UNDEFINED, color=Component.UNDEFINED, size=Component.UNDEFINED, width=Component.UNDEFINED, height=Component.UNDEFINED, theme=Component.UNDEFINED, label=Component.UNDEFINED, labelPosition=Component.UNDEFINED, className=Component.UNDEFINED, style=Component.UNDEFINED, **kwargs): 55 | self._prop_names = ['id', 'className', 'color', 'height', 'label', 'labelPosition', 'size', 'style', 'theme', 'value', 'width'] 56 | self._type = 'Indicator' 57 | self._namespace = 'dash_daq' 58 | self._valid_wildcard_attributes = [] 59 | self.available_properties = ['id', 'className', 'color', 'height', 'label', 'labelPosition', 'size', 'style', 'theme', 'value', 'width'] 60 | self.available_wildcard_properties = [] 61 | _explicit_args = kwargs.pop('_explicit_args') 62 | _locals = locals() 63 | _locals.update(kwargs) # For wildcard attrs 64 | args = {k: _locals[k] for k in _explicit_args if k != 'children'} 65 | for k in []: 66 | if k not in args: 67 | raise TypeError( 68 | 'Required argument `' + k + '` was not specified.') 69 | super(Indicator, self).__init__(**args) 70 | -------------------------------------------------------------------------------- /dash_daq/Joystick.py: -------------------------------------------------------------------------------- 1 | # AUTO GENERATED FILE - DO NOT EDIT 2 | 3 | from dash.development.base_component import Component, _explicitize_args 4 | 5 | 6 | class Joystick(Component): 7 | """A Joystick component. 8 | A joystick. 9 | 10 | Keyword arguments: 11 | 12 | - id (string; optional): 13 | The ID used to identify the Joystick in Dash callbacks. 14 | 15 | - angle (number; optional): 16 | Joystick angle in degrees, 0 = right, 90 = up, 180 = left, 270 = 17 | down. 18 | 19 | - className (string; optional): 20 | Class to apply to the root component element. 21 | 22 | - force (number; optional): 23 | Joystick force: distance between cursor and center in big-circle 24 | radii. 25 | 26 | - label (dict; optional): 27 | Description to be displayed alongside the control. To control 28 | styling, pass an object with label and style properties. 29 | 30 | `label` is a string | dict with keys: 31 | 32 | - label (string; optional) 33 | 34 | - style (dict; optional) 35 | 36 | - labelPosition (a value equal to: 'top', 'bottom'; default 'top'): 37 | Where the indicator label is positioned. 38 | 39 | - size (number; default 100): 40 | Size (width) of the component in pixels. 41 | 42 | - style (dict; optional): 43 | Style to apply to the root component element. 44 | 45 | - theme (dict; default light): 46 | Theme configuration to be set by a ThemeProvider.""" 47 | @_explicitize_args 48 | def __init__(self, id=Component.UNDEFINED, angle=Component.UNDEFINED, force=Component.UNDEFINED, size=Component.UNDEFINED, theme=Component.UNDEFINED, label=Component.UNDEFINED, labelPosition=Component.UNDEFINED, className=Component.UNDEFINED, style=Component.UNDEFINED, **kwargs): 49 | self._prop_names = ['id', 'angle', 'className', 'force', 'label', 'labelPosition', 'size', 'style', 'theme'] 50 | self._type = 'Joystick' 51 | self._namespace = 'dash_daq' 52 | self._valid_wildcard_attributes = [] 53 | self.available_properties = ['id', 'angle', 'className', 'force', 'label', 'labelPosition', 'size', 'style', 'theme'] 54 | self.available_wildcard_properties = [] 55 | _explicit_args = kwargs.pop('_explicit_args') 56 | _locals = locals() 57 | _locals.update(kwargs) # For wildcard attrs 58 | args = {k: _locals[k] for k in _explicit_args if k != 'children'} 59 | for k in []: 60 | if k not in args: 61 | raise TypeError( 62 | 'Required argument `' + k + '` was not specified.') 63 | super(Joystick, self).__init__(**args) 64 | -------------------------------------------------------------------------------- /dash_daq/LEDDisplay.py: -------------------------------------------------------------------------------- 1 | # AUTO GENERATED FILE - DO NOT EDIT 2 | 3 | from dash.development.base_component import Component, _explicitize_args 4 | 5 | 6 | class LEDDisplay(Component): 7 | """A LEDDisplay component. 8 | A 7-bar LED display component. 9 | 10 | Keyword arguments: 11 | 12 | - id (string; optional): 13 | The ID used to identify the display in Dash callbacks. 14 | 15 | - backgroundColor (string; default '#fff'): 16 | Color of the display's background. 17 | 18 | - className (string; optional): 19 | Class to apply to the root component element. 20 | 21 | - color (string; default colors.PRIMARY): 22 | Color of the display. 23 | 24 | - label (dict; optional): 25 | Description to be displayed alongside the control. To control 26 | styling, pass an object with label and style properties. 27 | 28 | `label` is a string | dict with keys: 29 | 30 | - label (string; optional) 31 | 32 | - style (dict; optional) 33 | 34 | - labelPosition (a value equal to: 'top', 'bottom'; default 'top'): 35 | Where the display label is positioned. 36 | 37 | - size (number; default 42): 38 | Size of the display. 39 | 40 | - style (dict; optional): 41 | Style to apply to the root component element. 42 | 43 | - theme (dict; default light): 44 | Theme configuration to be set by a ThemeProvider. 45 | 46 | - value (number | string; optional): 47 | Value to be displayed. A number or a string containing only digits 48 | (0-9), periods, and colons, and possibly starting with a minus 49 | sign.""" 50 | @_explicitize_args 51 | def __init__(self, id=Component.UNDEFINED, value=Component.UNDEFINED, color=Component.UNDEFINED, backgroundColor=Component.UNDEFINED, size=Component.UNDEFINED, theme=Component.UNDEFINED, label=Component.UNDEFINED, labelPosition=Component.UNDEFINED, className=Component.UNDEFINED, style=Component.UNDEFINED, **kwargs): 52 | self._prop_names = ['id', 'backgroundColor', 'className', 'color', 'label', 'labelPosition', 'size', 'style', 'theme', 'value'] 53 | self._type = 'LEDDisplay' 54 | self._namespace = 'dash_daq' 55 | self._valid_wildcard_attributes = [] 56 | self.available_properties = ['id', 'backgroundColor', 'className', 'color', 'label', 'labelPosition', 'size', 'style', 'theme', 'value'] 57 | self.available_wildcard_properties = [] 58 | _explicit_args = kwargs.pop('_explicit_args') 59 | _locals = locals() 60 | _locals.update(kwargs) # For wildcard attrs 61 | args = {k: _locals[k] for k in _explicit_args if k != 'children'} 62 | for k in []: 63 | if k not in args: 64 | raise TypeError( 65 | 'Required argument `' + k + '` was not specified.') 66 | super(LEDDisplay, self).__init__(**args) 67 | -------------------------------------------------------------------------------- /dash_daq/NumericInput.py: -------------------------------------------------------------------------------- 1 | # AUTO GENERATED FILE - DO NOT EDIT 2 | 3 | from dash.development.base_component import Component, _explicitize_args 4 | 5 | 6 | class NumericInput(Component): 7 | """A NumericInput component. 8 | A numeric input component that can be 9 | set to a value between some range. 10 | 11 | Keyword arguments: 12 | 13 | - id (string; optional): 14 | The ID used to identify this compnent in Dash callbacks. 15 | 16 | - className (string; optional): 17 | Class to apply to the root component element. 18 | 19 | - disabled (boolean; optional): 20 | If True, numeric input cannot changed. 21 | 22 | - label (dict; optional): 23 | Description to be displayed alongside the control. To control 24 | styling, pass an object with label and style properties. 25 | 26 | `label` is a string | dict with keys: 27 | 28 | - label (string; optional) 29 | 30 | - style (dict; optional) 31 | 32 | - labelPosition (a value equal to: 'top', 'bottom'; default 'top'): 33 | Where the numeric input label is positioned. 34 | 35 | - max (number; default 10): 36 | The maximum value of the numeric input. 37 | 38 | - min (number; default 0): 39 | The minimum value of the numeric input. 40 | 41 | - persisted_props (list of a value equal to: 'value's; default ['value']): 42 | Properties whose user interactions will persist after refreshing 43 | the component or the page. Since only `value` is allowed this prop 44 | can normally be ignored. 45 | 46 | - persistence (boolean | string | number; optional): 47 | Used to allow user interactions in this component to be persisted 48 | when the component - or the page - is refreshed. If `persisted` is 49 | truthy and hasn't changed from its previous value, a `value` that 50 | the user has changed while using the app will keep that change, as 51 | long as the new `value` also matches what was given originally. 52 | Used in conjunction with `persistence_type`. 53 | 54 | - persistence_type (a value equal to: 'local', 'session', 'memory'; default 'local'): 55 | Where persisted user changes will be stored: memory: only kept in 56 | memory, reset on page refresh. local: window.localStorage, data is 57 | kept after the browser quit. session: window.sessionStorage, data 58 | is cleared once the browser quit. 59 | 60 | - size (number; optional): 61 | The size (length) of the numeric input in pixels. 62 | 63 | - style (dict; default { display: 'flex', justifyContent: 'center' }): 64 | Style to apply to the root component element. 65 | 66 | - theme (dict; default light): 67 | Theme configuration to be set by a ThemeProvider. 68 | 69 | - value (number; optional): 70 | The value of numeric input.""" 71 | @_explicitize_args 72 | def __init__(self, id=Component.UNDEFINED, value=Component.UNDEFINED, size=Component.UNDEFINED, min=Component.UNDEFINED, max=Component.UNDEFINED, disabled=Component.UNDEFINED, theme=Component.UNDEFINED, label=Component.UNDEFINED, labelPosition=Component.UNDEFINED, className=Component.UNDEFINED, style=Component.UNDEFINED, persistence=Component.UNDEFINED, persisted_props=Component.UNDEFINED, persistence_type=Component.UNDEFINED, **kwargs): 73 | self._prop_names = ['id', 'className', 'disabled', 'label', 'labelPosition', 'max', 'min', 'persisted_props', 'persistence', 'persistence_type', 'size', 'style', 'theme', 'value'] 74 | self._type = 'NumericInput' 75 | self._namespace = 'dash_daq' 76 | self._valid_wildcard_attributes = [] 77 | self.available_properties = ['id', 'className', 'disabled', 'label', 'labelPosition', 'max', 'min', 'persisted_props', 'persistence', 'persistence_type', 'size', 'style', 'theme', 'value'] 78 | self.available_wildcard_properties = [] 79 | _explicit_args = kwargs.pop('_explicit_args') 80 | _locals = locals() 81 | _locals.update(kwargs) # For wildcard attrs 82 | args = {k: _locals[k] for k in _explicit_args if k != 'children'} 83 | for k in []: 84 | if k not in args: 85 | raise TypeError( 86 | 'Required argument `' + k + '` was not specified.') 87 | super(NumericInput, self).__init__(**args) 88 | -------------------------------------------------------------------------------- /dash_daq/PowerButton.py: -------------------------------------------------------------------------------- 1 | # AUTO GENERATED FILE - DO NOT EDIT 2 | 3 | from dash.development.base_component import Component, _explicitize_args 4 | 5 | 6 | class PowerButton(Component): 7 | """A PowerButton component. 8 | A power button component can be 9 | turned on and off. 10 | 11 | Keyword arguments: 12 | 13 | - id (string; optional): 14 | The ID used to identify this compnent in Dash callbacks. 15 | 16 | - className (string; optional): 17 | Class to apply to the root component element. 18 | 19 | - color (string; optional): 20 | The indicator color to display when power button is on. 21 | 22 | - disabled (boolean; optional): 23 | If True, power button cannot be clicked. 24 | 25 | - label (dict; optional): 26 | Description to be displayed alongside the button. To control 27 | styling, pass an object with label and style properties. 28 | 29 | `label` is a string | dict with keys: 30 | 31 | - label (string; optional) 32 | 33 | - style (dict; optional) 34 | 35 | - labelPosition (a value equal to: 'top', 'bottom'; default 'top'): 36 | Where the button label is positioned. 37 | 38 | - offButtonStyle (dict; optional): 39 | style to apply on switch off button. 40 | 41 | - on (boolean; default False): 42 | Whether or not the power button is on. 43 | 44 | - onButtonStyle (dict; optional): 45 | style to apply on switch on button. 46 | 47 | - persisted_props (list of a value equal to: 'on's; default ['on']): 48 | Properties whose user interactions will persist after refreshing 49 | the component or the page. Since only `on` is allowed this prop 50 | can normally be ignored. 51 | 52 | - persistence (boolean | string | number; optional): 53 | Used to allow user interactions in this component to be persisted 54 | when the component - or the page - is refreshed. If `persisted` is 55 | truthy and hasn't changed from its previous value, a `value` that 56 | the user has changed while using the app will keep that change, as 57 | long as the new `value` also matches what was given originally. 58 | Used in conjunction with `persistence_type`. 59 | 60 | - persistence_type (a value equal to: 'local', 'session', 'memory'; default 'local'): 61 | Where persisted user changes will be stored: memory: only kept in 62 | memory, reset on page refresh. local: window.localStorage, data is 63 | kept after the browser quit. session: window.sessionStorage, data 64 | is cleared once the browser quit. 65 | 66 | - size (number; default 48): 67 | The size (diameter) of the power button in pixels. 68 | 69 | - style (dict; optional): 70 | Style to apply to the root component element. 71 | 72 | - theme (dict; default light): 73 | Theme configuration to be set by a ThemeProvider.""" 74 | @_explicitize_args 75 | def __init__(self, id=Component.UNDEFINED, on=Component.UNDEFINED, color=Component.UNDEFINED, size=Component.UNDEFINED, disabled=Component.UNDEFINED, theme=Component.UNDEFINED, label=Component.UNDEFINED, labelPosition=Component.UNDEFINED, className=Component.UNDEFINED, style=Component.UNDEFINED, onButtonStyle=Component.UNDEFINED, offButtonStyle=Component.UNDEFINED, persistence=Component.UNDEFINED, persisted_props=Component.UNDEFINED, persistence_type=Component.UNDEFINED, **kwargs): 76 | self._prop_names = ['id', 'className', 'color', 'disabled', 'label', 'labelPosition', 'offButtonStyle', 'on', 'onButtonStyle', 'persisted_props', 'persistence', 'persistence_type', 'size', 'style', 'theme'] 77 | self._type = 'PowerButton' 78 | self._namespace = 'dash_daq' 79 | self._valid_wildcard_attributes = [] 80 | self.available_properties = ['id', 'className', 'color', 'disabled', 'label', 'labelPosition', 'offButtonStyle', 'on', 'onButtonStyle', 'persisted_props', 'persistence', 'persistence_type', 'size', 'style', 'theme'] 81 | self.available_wildcard_properties = [] 82 | _explicit_args = kwargs.pop('_explicit_args') 83 | _locals = locals() 84 | _locals.update(kwargs) # For wildcard attrs 85 | args = {k: _locals[k] for k in _explicit_args if k != 'children'} 86 | for k in []: 87 | if k not in args: 88 | raise TypeError( 89 | 'Required argument `' + k + '` was not specified.') 90 | super(PowerButton, self).__init__(**args) 91 | -------------------------------------------------------------------------------- /dash_daq/PrecisionInput.py: -------------------------------------------------------------------------------- 1 | # AUTO GENERATED FILE - DO NOT EDIT 2 | 3 | from dash.development.base_component import Component, _explicitize_args 4 | 5 | 6 | class PrecisionInput(Component): 7 | """A PrecisionInput component. 8 | A numeric input component that converts 9 | an input value to the desired precision. 10 | 11 | Keyword arguments: 12 | 13 | - id (string; optional): 14 | The ID used to identify this compnent in Dash callbacks. 15 | 16 | - className (string; optional): 17 | Class to apply to the root component element. 18 | 19 | - disabled (boolean; optional): 20 | If True, numeric input cannot be changed. 21 | 22 | - label (dict; optional): 23 | Description to be displayed alongside the scientific notation. To 24 | control styling, pass an object with label and style properties. 25 | 26 | `label` is a string | dict with keys: 27 | 28 | - label (string; optional) 29 | 30 | - style (dict; optional) 31 | 32 | - labelPosition (a value equal to: 'top', 'bottom'; default 'top'): 33 | Where the numeric input label is positioned. 34 | 35 | - max (number; default Number.MAX_SAFE_INTEGER): 36 | The maximum value of the numeric input. 37 | 38 | - min (number; default 0): 39 | The minimum value of the numeric input. 40 | 41 | - persisted_props (list of a value equal to: 'value's; default ['value']): 42 | Properties whose user interactions will persist after refreshing 43 | the component or the page. Since only `value` is allowed this prop 44 | can normally be ignored. 45 | 46 | - persistence (boolean | string | number; optional): 47 | Used to allow user interactions in this component to be persisted 48 | when the component - or the page - is refreshed. If `persisted` is 49 | truthy and hasn't changed from its previous value, a `value` that 50 | the user has changed while using the app will keep that change, as 51 | long as the new `value` also matches what was given originally. 52 | Used in conjunction with `persistence_type`. 53 | 54 | - persistence_type (a value equal to: 'local', 'session', 'memory'; default 'local'): 55 | Where persisted user changes will be stored: memory: only kept in 56 | memory, reset on page refresh. local: window.localStorage, data is 57 | kept after the browser quit. session: window.sessionStorage, data 58 | is cleared once the browser quit. 59 | 60 | - precision (number; default 2): 61 | Number of significant figures. 62 | 63 | - size (number; optional): 64 | The size (length) of the numeric input in pixels. 65 | 66 | - style (dict; optional): 67 | Style to apply to the root component element. 68 | 69 | - theme (dict; default light): 70 | Theme configuration to be set by a ThemeProvider. 71 | 72 | - value (number; optional): 73 | The value of numeric input.""" 74 | @_explicitize_args 75 | def __init__(self, id=Component.UNDEFINED, value=Component.UNDEFINED, size=Component.UNDEFINED, min=Component.UNDEFINED, max=Component.UNDEFINED, precision=Component.UNDEFINED, disabled=Component.UNDEFINED, theme=Component.UNDEFINED, label=Component.UNDEFINED, labelPosition=Component.UNDEFINED, className=Component.UNDEFINED, style=Component.UNDEFINED, persistence=Component.UNDEFINED, persisted_props=Component.UNDEFINED, persistence_type=Component.UNDEFINED, **kwargs): 76 | self._prop_names = ['id', 'className', 'disabled', 'label', 'labelPosition', 'max', 'min', 'persisted_props', 'persistence', 'persistence_type', 'precision', 'size', 'style', 'theme', 'value'] 77 | self._type = 'PrecisionInput' 78 | self._namespace = 'dash_daq' 79 | self._valid_wildcard_attributes = [] 80 | self.available_properties = ['id', 'className', 'disabled', 'label', 'labelPosition', 'max', 'min', 'persisted_props', 'persistence', 'persistence_type', 'precision', 'size', 'style', 'theme', 'value'] 81 | self.available_wildcard_properties = [] 82 | _explicit_args = kwargs.pop('_explicit_args') 83 | _locals = locals() 84 | _locals.update(kwargs) # For wildcard attrs 85 | args = {k: _locals[k] for k in _explicit_args if k != 'children'} 86 | for k in []: 87 | if k not in args: 88 | raise TypeError( 89 | 'Required argument `' + k + '` was not specified.') 90 | super(PrecisionInput, self).__init__(**args) 91 | -------------------------------------------------------------------------------- /dash_daq/StopButton.py: -------------------------------------------------------------------------------- 1 | # AUTO GENERATED FILE - DO NOT EDIT 2 | 3 | from dash.development.base_component import Component, _explicitize_args 4 | 5 | 6 | class StopButton(Component): 7 | """A StopButton component. 8 | A Stop button component 9 | 10 | Keyword arguments: 11 | 12 | - children (a list of or a singular dash component, string or number; optional): 13 | The children of the button. 14 | 15 | - id (string; optional): 16 | The ID used to identify this compnent in Dash callbacks. 17 | 18 | - buttonText (string; default 'Stop'): 19 | Text displayed in the button. 20 | 21 | - className (string; optional): 22 | Class to apply to the root component element. 23 | 24 | - disabled (boolean; optional): 25 | If True, button cannot be pressesd. 26 | 27 | - label (dict; optional): 28 | Description to be displayed alongside the button. To control 29 | styling, pass an object with label and style properties. 30 | 31 | `label` is a string | dict with keys: 32 | 33 | - label (string; optional) 34 | 35 | - style (dict; optional) 36 | 37 | - labelPosition (a value equal to: 'top', 'bottom'; default 'top'): 38 | Where the label is positioned. 39 | 40 | - n_clicks (number; default 0): 41 | Number of times the button was clicked. 42 | 43 | - size (number; default 92): 44 | The size (width) of the stop button in pixels. 45 | 46 | - style (dict; optional): 47 | Style to apply to the root component element. 48 | 49 | - theme (dict; optional): 50 | Theme configuration to be set by a ThemeProvider.""" 51 | @_explicitize_args 52 | def __init__(self, children=None, id=Component.UNDEFINED, size=Component.UNDEFINED, buttonText=Component.UNDEFINED, n_clicks=Component.UNDEFINED, disabled=Component.UNDEFINED, theme=Component.UNDEFINED, label=Component.UNDEFINED, labelPosition=Component.UNDEFINED, className=Component.UNDEFINED, style=Component.UNDEFINED, **kwargs): 53 | self._prop_names = ['children', 'id', 'buttonText', 'className', 'disabled', 'label', 'labelPosition', 'n_clicks', 'size', 'style', 'theme'] 54 | self._type = 'StopButton' 55 | self._namespace = 'dash_daq' 56 | self._valid_wildcard_attributes = [] 57 | self.available_properties = ['children', 'id', 'buttonText', 'className', 'disabled', 'label', 'labelPosition', 'n_clicks', 'size', 'style', 'theme'] 58 | self.available_wildcard_properties = [] 59 | _explicit_args = kwargs.pop('_explicit_args') 60 | _locals = locals() 61 | _locals.update(kwargs) # For wildcard attrs 62 | args = {k: _locals[k] for k in _explicit_args if k != 'children'} 63 | for k in []: 64 | if k not in args: 65 | raise TypeError( 66 | 'Required argument `' + k + '` was not specified.') 67 | super(StopButton, self).__init__(children=children, **args) 68 | -------------------------------------------------------------------------------- /dash_daq/ToggleSwitch.py: -------------------------------------------------------------------------------- 1 | # AUTO GENERATED FILE - DO NOT EDIT 2 | 3 | from dash.development.base_component import Component, _explicitize_args 4 | 5 | 6 | class ToggleSwitch(Component): 7 | """A ToggleSwitch component. 8 | A switch component that toggles between 9 | two values. 10 | 11 | Keyword arguments: 12 | 13 | - id (string; optional): 14 | The ID used to identify this compnent in Dash callbacks. 15 | 16 | - className (string; optional): 17 | Class to apply to the root component element. 18 | 19 | - color (string; optional): 20 | Color to highlight button/indicator. 21 | 22 | - disabled (boolean; optional): 23 | If True, switch cannot be clicked. 24 | 25 | - label (dict; optional): 26 | Description to be displayed alongside the control. To control 27 | styling, pass an object with label and style properties. 28 | 29 | `label` is a string | dict with keys: 30 | 31 | - label (string; optional) 32 | 33 | - style (dict; optional) 34 | 35 | Or list of string | dict with keys: 36 | 37 | - label (string; optional) 38 | 39 | - style (dict; optional)s 40 | 41 | - labelPosition (a value equal to: 'top', 'bottom'; default 'top'): 42 | Where the component label is positioned. 43 | 44 | - persisted_props (list of a value equal to: 'value's; default ['value']): 45 | Properties whose user interactions will persist after refreshing 46 | the component or the page. Since only `value` is allowed this prop 47 | can normally be ignored. 48 | 49 | - persistence (boolean | string | number; optional): 50 | Used to allow user interactions in this component to be persisted 51 | when the component - or the page - is refreshed. If `persisted` is 52 | truthy and hasn't changed from its previous value, a `value` that 53 | the user has changed while using the app will keep that change, as 54 | long as the new `value` also matches what was given originally. 55 | Used in conjunction with `persistence_type`. 56 | 57 | - persistence_type (a value equal to: 'local', 'session', 'memory'; default 'local'): 58 | Where persisted user changes will be stored: memory: only kept in 59 | memory, reset on page refresh. local: window.localStorage, data is 60 | kept after the browser quit. session: window.sessionStorage, data 61 | is cleared once the browser quit. 62 | 63 | - size (number; optional): 64 | The size of the switch. 65 | 66 | - style (dict; optional): 67 | Style to apply to the root object. 68 | 69 | - theme (dict; default light): 70 | Theme configuration to be set by a ThemeProvider. 71 | 72 | - value (boolean; default False): 73 | The state of the switch. 74 | 75 | - vertical (boolean; default False): 76 | If True, switch will be vertical instead of horizontal.""" 77 | @_explicitize_args 78 | def __init__(self, id=Component.UNDEFINED, value=Component.UNDEFINED, size=Component.UNDEFINED, color=Component.UNDEFINED, vertical=Component.UNDEFINED, disabled=Component.UNDEFINED, theme=Component.UNDEFINED, label=Component.UNDEFINED, labelPosition=Component.UNDEFINED, className=Component.UNDEFINED, style=Component.UNDEFINED, persistence=Component.UNDEFINED, persisted_props=Component.UNDEFINED, persistence_type=Component.UNDEFINED, **kwargs): 79 | self._prop_names = ['id', 'className', 'color', 'disabled', 'label', 'labelPosition', 'persisted_props', 'persistence', 'persistence_type', 'size', 'style', 'theme', 'value', 'vertical'] 80 | self._type = 'ToggleSwitch' 81 | self._namespace = 'dash_daq' 82 | self._valid_wildcard_attributes = [] 83 | self.available_properties = ['id', 'className', 'color', 'disabled', 'label', 'labelPosition', 'persisted_props', 'persistence', 'persistence_type', 'size', 'style', 'theme', 'value', 'vertical'] 84 | self.available_wildcard_properties = [] 85 | _explicit_args = kwargs.pop('_explicit_args') 86 | _locals = locals() 87 | _locals.update(kwargs) # For wildcard attrs 88 | args = {k: _locals[k] for k in _explicit_args if k != 'children'} 89 | for k in []: 90 | if k not in args: 91 | raise TypeError( 92 | 'Required argument `' + k + '` was not specified.') 93 | super(ToggleSwitch, self).__init__(**args) 94 | -------------------------------------------------------------------------------- /dash_daq/__init__.py: -------------------------------------------------------------------------------- 1 | import os as _os 2 | import dash as _dash 3 | import sys as _sys 4 | import json 5 | 6 | _basepath = _os.path.dirname(__file__) 7 | _filepath = _os.path.abspath(_os.path.join(_basepath, 'package-info.json')) 8 | 9 | with open(_filepath) as f: 10 | __version__ = json.loads(f.read())['version'] 11 | 12 | from ._imports_ import * # noqa: F401, F403, E402 13 | from ._imports_ import __all__ # noqa: E402 14 | 15 | async_resources = [ 16 | 'colorpicker', 17 | 'slider' 18 | ] 19 | 20 | _js_dist = [] 21 | 22 | _js_dist.extend([{ 23 | 'relative_package_path': 'async-{}.js'.format(async_resource), 24 | 'external_url': ( 25 | 'https://unpkg.com/dash-daq@{}' 26 | '/dash_daq/async-{}.js' 27 | ).format(__version__, async_resource), 28 | 'namespace': 'dash_daq', 29 | 'async': True 30 | } for async_resource in async_resources]) 31 | 32 | _js_dist.extend([{ 33 | 'relative_package_path': 'async-{}.js.map'.format(async_resource), 34 | 'external_url': ( 35 | 'https://unpkg.com/dash-daq@{}' 36 | '/dash_daq/async-{}.js.map' 37 | ).format(__version__, async_resource), 38 | 'namespace': 'dash_daq', 39 | 'dynamic': True 40 | } for async_resource in async_resources]) 41 | 42 | _js_dist.extend([ 43 | { 44 | "relative_package_path": "dash_daq.min.js", 45 | "external_url": ( 46 | "https://unpkg.com/dash-daq@{}" 47 | "/dash_daq/dash_daq.min.js" 48 | ).format(__version__), 49 | "namespace": "dash_daq" 50 | } 51 | ]) 52 | 53 | _js_dist.extend([ 54 | { 55 | "relative_package_path": "dash_daq.min.js.map", 56 | "external_url": ( 57 | "https://unpkg.com/dash-daq@{}" 58 | "/dash_daq/dash_daq.min.js.map" 59 | ).format(__version__), 60 | "namespace": "dash_daq", 61 | 'dynamic': True 62 | } 63 | ]) 64 | _css_dist = [] 65 | 66 | 67 | for _component in __all__: 68 | setattr(locals()[_component], '_js_dist', _js_dist) 69 | -------------------------------------------------------------------------------- /dash_daq/_imports_.py: -------------------------------------------------------------------------------- 1 | from .BooleanSwitch import BooleanSwitch 2 | from .ColorPicker import ColorPicker 3 | from .DarkThemeProvider import DarkThemeProvider 4 | from .Gauge import Gauge 5 | from .GraduatedBar import GraduatedBar 6 | from .Indicator import Indicator 7 | from .Joystick import Joystick 8 | from .Knob import Knob 9 | from .LEDDisplay import LEDDisplay 10 | from .NumericInput import NumericInput 11 | from .PowerButton import PowerButton 12 | from .PrecisionInput import PrecisionInput 13 | from .Slider import Slider 14 | from .StopButton import StopButton 15 | from .Tank import Tank 16 | from .Thermometer import Thermometer 17 | from .ToggleSwitch import ToggleSwitch 18 | 19 | __all__ = [ 20 | "BooleanSwitch", 21 | "ColorPicker", 22 | "DarkThemeProvider", 23 | "Gauge", 24 | "GraduatedBar", 25 | "Indicator", 26 | "Joystick", 27 | "Knob", 28 | "LEDDisplay", 29 | "NumericInput", 30 | "PowerButton", 31 | "PrecisionInput", 32 | "Slider", 33 | "StopButton", 34 | "Tank", 35 | "Thermometer", 36 | "ToggleSwitch" 37 | ] -------------------------------------------------------------------------------- /dash_daq/package-info.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "dash-daq", 3 | "version": "0.6.0", 4 | "engines": { 5 | "node": ">=8" 6 | }, 7 | "description": "DAQ components for Dash", 8 | "repository": { 9 | "type": "git", 10 | "url": "git://github.com/plotly/dash-daq.git" 11 | }, 12 | "bugs": { 13 | "url": "https://github.com/plotly/dash-daq/issues" 14 | }, 15 | "homepage": "https://github.com/plotly/dash-daq", 16 | "main": "dash_daq/dash_daq.min.js", 17 | "author": "The Plotly Team ", 18 | "maintainer": "The Plotly Team ", 19 | "license": "MIT", 20 | "scripts": { 21 | "copy-lib": "copyfiles -u 1 lib/* dash_daq", 22 | "dash-demo": "python demo.py", 23 | "install-local": "pip install -e .", 24 | "lint": "eslint --fix --ignore-path .eslintignore src/", 25 | "start": "npm run build:dev", 26 | "build:js": "webpack --mode production", 27 | "build:js-dev": "webpack --mode development", 28 | "build:py": "python get_version_info.py && yarn copy-lib && dash-generate-components ./src/components dash_daq -p package-info.json", 29 | "build:r": "dash-generate-components ./src/components dash_daq -p package-info.json --r-prefix='daq'", 30 | "build": "npm run test && npm run lint && npm run build:js && npm run build:py && npm run build:r", 31 | "postbuild": "es-check es5 dash_daq/*.js", 32 | "build:dev": "npm run build:js-dev && npm run build:py", 33 | "build-tarball": "npm run build && python setup.py sdist", 34 | "test": "jest src/components/__tests__", 35 | "test-gauge": "jest src/components/__tests__/Gauge.test.js", 36 | "test:frontend-cov": "jest --coverage --silent", 37 | "test:watch": "jest --watch", 38 | "uninstall-local": "pip uninstall dash_daq -y", 39 | "prettier": "yarn prettier-src && yarn prettier-tests", 40 | "prettier-src": "prettier --single-quote --print-width=100 --write src/**/*.js", 41 | "prettier-tests": "prettier --single-quote --print-width=100 --write src/components/__tests__/**/*.js", 42 | "prettier-restage": "git update-index --again" 43 | }, 44 | "dependencies": { 45 | "color": "^3.0.0", 46 | "conic-gradient": "^1.0.0", 47 | "copyfiles": "^1.2.0", 48 | "dash-components-archetype": "^0.2.11", 49 | "deep-equal": "^1.0.1", 50 | "nipplejs": "^0.7.1", 51 | "prop-types": "^15.5.9", 52 | "ramda": "^0.25.0", 53 | "rc-slider": "^9.1.0", 54 | "react": "16.13.0", 55 | "react-color": "^2.18.0", 56 | "react-dom": "16.13.0", 57 | "react-numeric-input": "^2.2.3", 58 | "styled-components": "^4.4.0", 59 | "tinygradient": "^0.4.0", 60 | "webpack": "^4.41.0", 61 | "yarn": "^1.22.11" 62 | }, 63 | "devDependencies": { 64 | "@babel/core": "^7.6.0", 65 | "@babel/plugin-syntax-dynamic-import": "^7.2.0", 66 | "@babel/preset-env": "^7.6.0", 67 | "@babel/preset-react": "^7.0.0", 68 | "@plotly/webpack-dash-dynamic-import": "^1.1.4", 69 | "babel-eslint": "^10.0.3", 70 | "babel-loader": "^8.0.6", 71 | "chalk": "^2.3.1", 72 | "css-loader": "^3.4.2", 73 | "dash-components-archetype-dev": "^0.2.11", 74 | "enzyme": "^3.10.0", 75 | "enzyme-adapter-react-16": "^1.14.0", 76 | "es-check": "^5.0.0", 77 | "fs-extra": "^5.0.0", 78 | "identity-obj-proxy": "^3.0.0", 79 | "jest": "^24.9.0", 80 | "jest-canvas-mock": "^2.1.1", 81 | "pre-commit": "^1.2.2", 82 | "prettier": "^1.10.2", 83 | "react-docgen": "^3.0.0", 84 | "react-docgen-markdown-renderer": "^1.0.2", 85 | "react-test-renderer": "^16.8.6", 86 | "sinon": "^4.3.0", 87 | "style-loader": "^1.1.3", 88 | "webpack-cli": "^3.3.9" 89 | }, 90 | "jest": { 91 | "coveragePathIgnorePatterns": [ 92 | "/src/styled", 93 | "/src/helpers" 94 | ], 95 | "testURL": "http://localhost", 96 | "setupFiles": [ 97 | "jest-canvas-mock" 98 | ], 99 | "moduleNameMapper": { 100 | "\\.css": "identity-obj-proxy" 101 | } 102 | }, 103 | "files": [ 104 | "dash_daq/*{.js,.map}" 105 | ], 106 | "pre-commit": [ 107 | "test", 108 | "prettier", 109 | "prettier-restage" 110 | ], 111 | "keywords": [ 112 | "dash", 113 | "daq", 114 | "components" 115 | ] 116 | } 117 | -------------------------------------------------------------------------------- /demo/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /demo/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | 4 | import Demo from './Demo.react'; 5 | 6 | // Fix for rendering React externally: 7 | // See https://github.com/gaearon/react-hot-loader/tree/v1.3.1/docs#usage-with-external-react 8 | const rootInstance = ReactDOM.render( 9 | , 10 | document.getElementById('react-demo-entry-point') 11 | ); 12 | 13 | /* eslint-disable */ 14 | require('react-hot-loader/Injection').RootInstanceProvider.injectProvider({ 15 | /* eslint-enable */ 16 | getRootInstances: function () { 17 | // Help React Hot Loader figure out the root component instances on the page: 18 | return [rootInstance]; 19 | } 20 | }); 21 | -------------------------------------------------------------------------------- /get_version_info.py: -------------------------------------------------------------------------------- 1 | import os 2 | import json 3 | import sys 4 | 5 | package_file = os.path.abspath(os.path.join(os.path.dirname(__file__), 'package.json')) 6 | 7 | with open(package_file) as f: 8 | package = json.load(f) 9 | 10 | package_info = dict( 11 | name=package['name'].replace(' ', '_').replace('-', '_'), 12 | version=package['version'], 13 | author=package['author'] 14 | ) 15 | 16 | package_info_file = os.path.abspath(os.path.join( 17 | os.path.dirname(__file__), os.path.join( 18 | 'dash_daq', 'package-info.json' 19 | ) 20 | )) 21 | 22 | with open(package_info_file, 'w') as f: 23 | f.write(json.dumps(package_info)) 24 | -------------------------------------------------------------------------------- /man/daqBooleanSwitch.Rd: -------------------------------------------------------------------------------- 1 | % Auto-generated: do not edit by hand 2 | \name{daqBooleanSwitch} 3 | 4 | \alias{daqBooleanSwitch} 5 | 6 | \title{BooleanSwitch component} 7 | 8 | \description{ 9 | A switch component that toggles between on and off. 10 | } 11 | 12 | \usage{ 13 | daqBooleanSwitch(id=NULL, className=NULL, color=NULL, disabled=NULL, 14 | label=NULL, labelPosition=NULL, on=NULL, 15 | persisted_props=NULL, persistence=NULL, 16 | persistence_type=NULL, size=NULL, style=NULL, theme=NULL, 17 | vertical=NULL) 18 | } 19 | 20 | \arguments{ 21 | \item{id}{Character. The ID used to identify this compnent in Dash callbacks} 22 | 23 | \item{className}{Character. Class to apply to the root component element.} 24 | 25 | \item{color}{Character. Color to highlight active switch background} 26 | 27 | \item{disabled}{Logical. If true, switch cannot be clicked} 28 | 29 | \item{label}{Character | lists containing elements 'style', 'label'. 30 | those elements have the following types: 31 | - style (named list; optional) 32 | - label (character; optional). Description to be displayed alongside the control. To control styling, 33 | pass an object with label and style properties.} 34 | 35 | \item{labelPosition}{A value equal to: 'top', 'bottom'. Where the component label is positioned.} 36 | 37 | \item{on}{Logical. Whether or not the switch is on} 38 | 39 | \item{persisted_props}{List of a value equal to: 'on's. Properties whose user interactions will persist after refreshing the 40 | component or the page. Since only `on` is allowed this prop can 41 | normally be ignored.} 42 | 43 | \item{persistence}{Logical | character | numeric. Used to allow user interactions in this component to be persisted when 44 | the component - or the page - is refreshed. If `persisted` is truthy and 45 | hasn't changed from its previous value, a `value` that the user has 46 | changed while using the app will keep that change, as long as 47 | the new `value` also matches what was given originally. 48 | Used in conjunction with `persistence_type`.} 49 | 50 | \item{persistence_type}{A value equal to: 'local', 'session', 'memory'. Where persisted user changes will be stored: 51 | memory: only kept in memory, reset on page refresh. 52 | local: window.localStorage, data is kept after the browser quit. 53 | session: window.sessionStorage, data is cleared once the browser quit.} 54 | 55 | \item{size}{Numeric. size of the switch} 56 | 57 | \item{style}{Named list. Style to apply to the root object.} 58 | 59 | \item{theme}{Named list. Theme configuration to be set by a ThemeProvider} 60 | 61 | \item{vertical}{Logical. If true, switch will be vertical instead 62 | of horizontal} 63 | } 64 | 65 | \value{named list of JSON elements corresponding to React.js properties and their values} 66 | 67 | -------------------------------------------------------------------------------- /man/daqColorPicker.Rd: -------------------------------------------------------------------------------- 1 | % Auto-generated: do not edit by hand 2 | \name{daqColorPicker} 3 | 4 | \alias{daqColorPicker} 5 | 6 | \title{ColorPicker component} 7 | 8 | \description{ 9 | A color picker. 10 | } 11 | 12 | \usage{ 13 | daqColorPicker(id=NULL, className=NULL, disabled=NULL, label=NULL, 14 | labelPosition=NULL, persisted_props=NULL, persistence=NULL, 15 | persistence_type=NULL, size=NULL, style=NULL, theme=NULL, 16 | value=NULL) 17 | } 18 | 19 | \arguments{ 20 | \item{id}{Character. The ID used to identify the color picker in Dash callbacks} 21 | 22 | \item{className}{Character. Class to apply to the root component element} 23 | 24 | \item{disabled}{Logical. If true, color cannot be picked.} 25 | 26 | \item{label}{Character | lists containing elements 'style', 'label'. 27 | those elements have the following types: 28 | - style (named list; optional) 29 | - label (character; optional). Description to be displayed alongside the control. To control styling, 30 | pass an object with label and style properties} 31 | 32 | \item{labelPosition}{A value equal to: 'top', 'bottom'. Where the indicator label is positioned} 33 | 34 | \item{persisted_props}{List of a value equal to: 'value's. Properties whose user interactions will persist after refreshing the 35 | component or the page. Since only `value` is allowed this prop can 36 | normally be ignored.} 37 | 38 | \item{persistence}{Logical | character | numeric. Used to allow user interactions in this component to be persisted when 39 | the component - or the page - is refreshed. If `persisted` is truthy and 40 | hasn't changed from its previous value, a `value` that the user has 41 | changed while using the app will keep that change, as long as 42 | the new `value` also matches what was given originally. 43 | Used in conjunction with `persistence_type`.} 44 | 45 | \item{persistence_type}{A value equal to: 'local', 'session', 'memory'. Where persisted user changes will be stored: 46 | memory: only kept in memory, reset on page refresh. 47 | local: window.localStorage, data is kept after the browser quit. 48 | session: window.sessionStorage, data is cleared once the browser quit.} 49 | 50 | \item{size}{Numeric. Size (width) of the component in pixels} 51 | 52 | \item{style}{Named list. Style to apply to the root component element} 53 | 54 | \item{theme}{Named list. Theme configuration to be set by a ThemeProvider} 55 | 56 | \item{value}{Lists containing elements 'hex', 'rbg'. 57 | those elements have the following types: 58 | - hex (character; optional): hex string 59 | - rbg (optional): rgb/rgba object. rbg has the following type: lists containing elements 'r', 'g', 'b', 'a'. 60 | those elements have the following types: 61 | - r (numeric; optional) 62 | - g (numeric; optional) 63 | - b (numeric; optional) 64 | - a (numeric; optional). Color value of the picker} 65 | } 66 | 67 | \value{named list of JSON elements corresponding to React.js properties and their values} 68 | 69 | -------------------------------------------------------------------------------- /man/daqDarkThemeProvider.Rd: -------------------------------------------------------------------------------- 1 | % Auto-generated: do not edit by hand 2 | \name{daqDarkThemeProvider} 3 | 4 | \alias{daqDarkThemeProvider} 5 | 6 | \title{DarkThemeProvider component} 7 | 8 | \description{ 9 | DarkThemeProvider is a component that is placed at the root of the component tree to make all components match the dark theme 10 | } 11 | 12 | \usage{ 13 | daqDarkThemeProvider(children=NULL, theme=NULL) 14 | } 15 | 16 | \arguments{ 17 | \item{children}{List of a list of or a singular dash component, string or numbers | a list of or a singular dash component, string or number. The children of this component} 18 | 19 | \item{theme}{Lists containing elements 'primary', 'secondary', 'detail', 'dark'. 20 | those elements have the following types: 21 | - primary (character; optional): highlight color 22 | - secondary (character; optional): supporting color 23 | - detail (character; optional): color used for ui details, like borders 24 | - dark (logical; optional): true for dark mode, false for light. Theme object to override with a custom theme} 25 | } 26 | 27 | \value{named list of JSON elements corresponding to React.js properties and their values} 28 | 29 | -------------------------------------------------------------------------------- /man/daqGauge.Rd: -------------------------------------------------------------------------------- 1 | % Auto-generated: do not edit by hand 2 | \name{daqGauge} 3 | 4 | \alias{daqGauge} 5 | 6 | \title{Gauge component} 7 | 8 | \description{ 9 | A Gauge component that points to a value between some range. 10 | } 11 | 12 | \usage{ 13 | daqGauge(id=NULL, base=NULL, className=NULL, color=NULL, digits=NULL, 14 | exceedMessage=NULL, label=NULL, labelPosition=NULL, 15 | lagingMessage=NULL, logarithmic=NULL, max=NULL, min=NULL, 16 | scale=NULL, showCurrentValue=NULL, size=NULL, style=NULL, 17 | textColor=NULL, theme=NULL, units=NULL, value=NULL) 18 | } 19 | 20 | \arguments{ 21 | \item{id}{Character. The ID used to identify this compnent in Dash callbacks} 22 | 23 | \item{base}{Numeric. Base to be used in logarithmic scale.} 24 | 25 | \item{className}{Character. Class to apply to the root component element.} 26 | 27 | \item{color}{Character | lists containing elements 'default', 'gradient', 'ranges'. 28 | those elements have the following types: 29 | - default (character; optional): color used for current value text and other minor accents 30 | - gradient (logical; optional): display ranges as a gradient between given colors. 31 | - ranges (optional): define multiple color ranges on the gauge's track. 32 | the key determines the color of the range and 33 | the value is the start,end of the range itself. 34 | ranges must be contiguous along the entirety 35 | of the gauge's range of values.. ranges has the following type: lists containing elements 'color'. 36 | those elements have the following types: 37 | - color (list of numeric | list of numericss; optional). Color configuration for the gauge's track.} 38 | 39 | \item{digits}{Numeric. Number of digits for current value} 40 | 41 | \item{exceedMessage}{Character. Warning message when value exceed max} 42 | 43 | \item{label}{Character | lists containing elements 'style', 'label'. 44 | those elements have the following types: 45 | - style (named list; optional) 46 | - label (character; optional). Description to be displayed alongside the control. To control styling, pass an object with label and style properties.} 47 | 48 | \item{labelPosition}{A value equal to: 'top', 'bottom'. Where the component label is positioned.} 49 | 50 | \item{lagingMessage}{Character. Warning message when value is laging from min} 51 | 52 | \item{logarithmic}{Logical. If set to true, a logarithmic scale will be 53 | used.} 54 | 55 | \item{max}{Numeric. The maximum value of the gauge. If logarithmic, 56 | represents the maximum exponent.} 57 | 58 | \item{min}{Numeric. The minimum value of the gauge. If logarithmic, 59 | represents the minimum exponent.} 60 | 61 | \item{scale}{Lists containing elements 'start', 'interval', 'labelinterval', 'custom'. 62 | those elements have the following types: 63 | - start (numeric; optional): value to start the scale from. defaults 64 | to min. 65 | - interval (numeric; optional): interval by which the scale goes up. attempts 66 | to dynamically divide min-max range by 67 | default. 68 | - labelinterval (numeric; optional): interval by which labels are added to 69 | scale marks. defaults to 2 (every other 70 | mark has a label). 71 | - custom (optional): custom scale marks. the key determines the position 72 | and the value determines what will show. if you want 73 | to set the style of a specific mark point, the value 74 | should be an object which contains style and label 75 | properties. custom has the following type: numeric | lists containing elements 'style', 'label'. 76 | those elements have the following types: 77 | - style (character; optional) 78 | - label (character; optional). Configuration for the component scale.} 79 | 80 | \item{showCurrentValue}{Logical. If true, the current value of the gauge 81 | will be displayed} 82 | 83 | \item{size}{Numeric. The size (diameter) of the gauge in pixels} 84 | 85 | \item{style}{Named list. Style to apply to the root component element.} 86 | 87 | \item{textColor}{Character. text color for theme} 88 | 89 | \item{theme}{Named list. Theme configuration to be set by a ThemeProvider} 90 | 91 | \item{units}{Character. Label for the current value} 92 | 93 | \item{value}{Numeric. The value of gauge. If logarithmic, the displayed 94 | value will be the logarithm of the inputted value.} 95 | } 96 | 97 | \value{named list of JSON elements corresponding to React.js properties and their values} 98 | 99 | -------------------------------------------------------------------------------- /man/daqGraduatedBar.Rd: -------------------------------------------------------------------------------- 1 | % Auto-generated: do not edit by hand 2 | \name{daqGraduatedBar} 3 | 4 | \alias{daqGraduatedBar} 5 | 6 | \title{GraduatedBar component} 7 | 8 | \description{ 9 | A graduated bar component that displays a value within some range as a percentage. 10 | } 11 | 12 | \usage{ 13 | daqGraduatedBar(id=NULL, className=NULL, color=NULL, label=NULL, 14 | labelPosition=NULL, max=NULL, min=NULL, 15 | showCurrentValue=NULL, size=NULL, step=NULL, style=NULL, 16 | theme=NULL, value=NULL, vertical=NULL) 17 | } 18 | 19 | \arguments{ 20 | \item{id}{Character. The ID used to identify this compnent in Dash callbacks} 21 | 22 | \item{className}{Character. Class to apply to the root component element.} 23 | 24 | \item{color}{Character | lists containing elements 'default', 'gradient', 'ranges'. 25 | those elements have the following types: 26 | - default (character; optional): fallback color to use when color.ranges 27 | has gaps. 28 | - gradient (logical; optional): display ranges as a gradient between given colors. 29 | requires color.ranges to be contiguous along 30 | the entirety of the graduated bar's range of values. 31 | - ranges (optional): define multiple color ranges on the graduated bar's track. 32 | the key determines the color of the range and 33 | the value is the start,end of the range itself.. ranges has the following type: lists containing elements 'color'. 34 | those elements have the following types: 35 | - color (list of numerics; optional). Color configuration for the graduated bar's 36 | progress blocks.} 37 | 38 | \item{label}{Character | lists containing elements 'style', 'label'. 39 | those elements have the following types: 40 | - style (named list; optional) 41 | - label (character; optional). Description to be displayed alongside the control. To control styling, pass an object with label and style properties.} 42 | 43 | \item{labelPosition}{A value equal to: 'top', 'bottom'. Where the component label is positioned.} 44 | 45 | \item{max}{Numeric. The maximum value of the graduated bar} 46 | 47 | \item{min}{Numeric. The minimum value of the graduated bar} 48 | 49 | \item{showCurrentValue}{Logical. If true, the current percentage 50 | of the bar will be displayed} 51 | 52 | \item{size}{Numeric. The size (length) of the graduated bar in pixels} 53 | 54 | \item{step}{Numeric. Value by which progress blocks appear} 55 | 56 | \item{style}{Named list. Style to apply to the root component element.} 57 | 58 | \item{theme}{Named list. Theme configuration to be set by a ThemeProvider} 59 | 60 | \item{value}{Numeric. The value of the graduated bar} 61 | 62 | \item{vertical}{Logical. If true, will display bar vertically instead of horizontally} 63 | } 64 | 65 | \value{named list of JSON elements corresponding to React.js properties and their values} 66 | 67 | -------------------------------------------------------------------------------- /man/daqIndicator.Rd: -------------------------------------------------------------------------------- 1 | % Auto-generated: do not edit by hand 2 | \name{daqIndicator} 3 | 4 | \alias{daqIndicator} 5 | 6 | \title{Indicator component} 7 | 8 | \description{ 9 | A boolean indicator LED. 10 | } 11 | 12 | \usage{ 13 | daqIndicator(id=NULL, className=NULL, color=NULL, height=NULL, 14 | label=NULL, labelPosition=NULL, size=NULL, style=NULL, 15 | theme=NULL, value=NULL, width=NULL) 16 | } 17 | 18 | \arguments{ 19 | \item{id}{Character. The ID used to identify the indicator in Dash callbacks} 20 | 21 | \item{className}{Character. Class to apply to the root component element} 22 | 23 | \item{color}{Character. Color of the indicator} 24 | 25 | \item{height}{Numeric. Height of the component. Set both width and height for a rectangular indicator} 26 | 27 | \item{label}{Character | lists containing elements 'style', 'label'. 28 | those elements have the following types: 29 | - style (named list; optional) 30 | - label (character; optional). Description to be displayed alongside the control. To control styling, 31 | pass an object with label and style properties} 32 | 33 | \item{labelPosition}{A value equal to: 'top', 'bottom', 'right', 'left'. Where the indicator label is positioned} 34 | 35 | \item{size}{Numeric. Size of the component. Either use this or width and height} 36 | 37 | \item{style}{Named list. Style to apply to the root component element} 38 | 39 | \item{theme}{Named list. Theme configuration to be set by a ThemeProvider} 40 | 41 | \item{value}{Logical. If true, indicator is illuminated} 42 | 43 | \item{width}{Numeric. Width of the component. Set both width and height for a rectangular indicator} 44 | } 45 | 46 | \value{named list of JSON elements corresponding to React.js properties and their values} 47 | 48 | -------------------------------------------------------------------------------- /man/daqJoystick.Rd: -------------------------------------------------------------------------------- 1 | % Auto-generated: do not edit by hand 2 | \name{daqJoystick} 3 | 4 | \alias{daqJoystick} 5 | 6 | \title{Joystick component} 7 | 8 | \description{ 9 | A joystick. 10 | } 11 | 12 | \usage{ 13 | daqJoystick(id=NULL, angle=NULL, className=NULL, force=NULL, label=NULL, 14 | labelPosition=NULL, size=NULL, style=NULL, theme=NULL) 15 | } 16 | 17 | \arguments{ 18 | \item{id}{Character. The ID used to identify the Joystick in Dash callbacks} 19 | 20 | \item{angle}{Numeric. Joystick angle in degrees, 0 = right, 90 = up, 180 = left, 270 = down} 21 | 22 | \item{className}{Character. Class to apply to the root component element} 23 | 24 | \item{force}{Numeric. Joystick force: distance between cursor and center in big-circle radii} 25 | 26 | \item{label}{Character | lists containing elements 'style', 'label'. 27 | those elements have the following types: 28 | - style (named list; optional) 29 | - label (character; optional). Description to be displayed alongside the control. To control styling, 30 | pass an object with label and style properties} 31 | 32 | \item{labelPosition}{A value equal to: 'top', 'bottom'. Where the indicator label is positioned} 33 | 34 | \item{size}{Numeric. Size (width) of the component in pixels} 35 | 36 | \item{style}{Named list. Style to apply to the root component element} 37 | 38 | \item{theme}{Named list. Theme configuration to be set by a ThemeProvider} 39 | } 40 | 41 | \value{named list of JSON elements corresponding to React.js properties and their values} 42 | 43 | -------------------------------------------------------------------------------- /man/daqLEDDisplay.Rd: -------------------------------------------------------------------------------- 1 | % Auto-generated: do not edit by hand 2 | \name{daqLEDDisplay} 3 | 4 | \alias{daqLEDDisplay} 5 | 6 | \title{LEDDisplay component} 7 | 8 | \description{ 9 | A 7-bar LED display component. 10 | } 11 | 12 | \usage{ 13 | daqLEDDisplay(id=NULL, backgroundColor=NULL, className=NULL, color=NULL, 14 | label=NULL, labelPosition=NULL, size=NULL, style=NULL, 15 | theme=NULL, value=NULL) 16 | } 17 | 18 | \arguments{ 19 | \item{id}{Character. The ID used to identify the display in Dash callbacks} 20 | 21 | \item{backgroundColor}{Character. Color of the display's background} 22 | 23 | \item{className}{Character. Class to apply to the root component element} 24 | 25 | \item{color}{Character. Color of the display} 26 | 27 | \item{label}{Character | lists containing elements 'style', 'label'. 28 | those elements have the following types: 29 | - style (named list; optional) 30 | - label (character; optional). Description to be displayed alongside the control. To control styling, 31 | pass an object with label and style properties} 32 | 33 | \item{labelPosition}{A value equal to: 'top', 'bottom'. Where the display label is positioned} 34 | 35 | \item{size}{Numeric. Size of the display} 36 | 37 | \item{style}{Named list. Style to apply to the root component element} 38 | 39 | \item{theme}{Named list. Theme configuration to be set by a ThemeProvider} 40 | 41 | \item{value}{Numeric | character. Value to be displayed. A number or a string 42 | containing only digits (0-9), periods, and colons, 43 | and possibly starting with a minus sign.} 44 | } 45 | 46 | \value{named list of JSON elements corresponding to React.js properties and their values} 47 | 48 | -------------------------------------------------------------------------------- /man/daqNumericInput.Rd: -------------------------------------------------------------------------------- 1 | % Auto-generated: do not edit by hand 2 | \name{daqNumericInput} 3 | 4 | \alias{daqNumericInput} 5 | 6 | \title{NumericInput component} 7 | 8 | \description{ 9 | A numeric input component that can be set to a value between some range. 10 | } 11 | 12 | \usage{ 13 | daqNumericInput(id=NULL, className=NULL, disabled=NULL, label=NULL, 14 | labelPosition=NULL, max=NULL, min=NULL, 15 | persisted_props=NULL, persistence=NULL, 16 | persistence_type=NULL, size=NULL, style=NULL, theme=NULL, 17 | value=NULL) 18 | } 19 | 20 | \arguments{ 21 | \item{id}{Character. The ID used to identify this compnent in Dash callbacks} 22 | 23 | \item{className}{Character. Class to apply to the root component element.} 24 | 25 | \item{disabled}{Logical. If true, numeric input cannot changed.} 26 | 27 | \item{label}{Character | lists containing elements 'style', 'label'. 28 | those elements have the following types: 29 | - style (named list; optional) 30 | - label (character; optional). Description to be displayed alongside the control. To control styling, 31 | pass an object with label and style properties.} 32 | 33 | \item{labelPosition}{A value equal to: 'top', 'bottom'. Where the numeric input label is positioned.} 34 | 35 | \item{max}{Numeric. The maximum value of the numeric input} 36 | 37 | \item{min}{Numeric. The minimum value of the numeric input} 38 | 39 | \item{persisted_props}{List of a value equal to: 'value's. Properties whose user interactions will persist after refreshing the 40 | component or the page. Since only `value` is allowed this prop can 41 | normally be ignored.} 42 | 43 | \item{persistence}{Logical | character | numeric. Used to allow user interactions in this component to be persisted when 44 | the component - or the page - is refreshed. If `persisted` is truthy and 45 | hasn't changed from its previous value, a `value` that the user has 46 | changed while using the app will keep that change, as long as 47 | the new `value` also matches what was given originally. 48 | Used in conjunction with `persistence_type`.} 49 | 50 | \item{persistence_type}{A value equal to: 'local', 'session', 'memory'. Where persisted user changes will be stored: 51 | memory: only kept in memory, reset on page refresh. 52 | local: window.localStorage, data is kept after the browser quit. 53 | session: window.sessionStorage, data is cleared once the browser quit.} 54 | 55 | \item{size}{Numeric. The size (length) of the numeric input in pixels} 56 | 57 | \item{style}{Named list. Style to apply to the root component element.} 58 | 59 | \item{theme}{Named list. Theme configuration to be set by a ThemeProvider} 60 | 61 | \item{value}{Numeric. The value of numeric input} 62 | } 63 | 64 | \value{named list of JSON elements corresponding to React.js properties and their values} 65 | 66 | -------------------------------------------------------------------------------- /man/daqPowerButton.Rd: -------------------------------------------------------------------------------- 1 | % Auto-generated: do not edit by hand 2 | \name{daqPowerButton} 3 | 4 | \alias{daqPowerButton} 5 | 6 | \title{PowerButton component} 7 | 8 | \description{ 9 | A power button component can be turned on and off. 10 | } 11 | 12 | \usage{ 13 | daqPowerButton(id=NULL, className=NULL, color=NULL, disabled=NULL, 14 | label=NULL, labelPosition=NULL, offButtonStyle=NULL, 15 | on=NULL, onButtonStyle=NULL, persisted_props=NULL, 16 | persistence=NULL, persistence_type=NULL, size=NULL, 17 | style=NULL, theme=NULL) 18 | } 19 | 20 | \arguments{ 21 | \item{id}{Character. The ID used to identify this compnent in Dash callbacks} 22 | 23 | \item{className}{Character. Class to apply to the root component element.} 24 | 25 | \item{color}{Character. The indicator color to display when power button is on} 26 | 27 | \item{disabled}{Logical. If true, power button cannot be clicked} 28 | 29 | \item{label}{Character | lists containing elements 'style', 'label'. 30 | those elements have the following types: 31 | - style (named list; optional) 32 | - label (character; optional). Description to be displayed alongside the button. To control styling, pass an object with label and style properties.} 33 | 34 | \item{labelPosition}{A value equal to: 'top', 'bottom'. Where the button label is positioned.} 35 | 36 | \item{offButtonStyle}{Named list. style to apply on switch off button} 37 | 38 | \item{on}{Logical. Whether or not the power button is on} 39 | 40 | \item{onButtonStyle}{Named list. style to apply on switch on button} 41 | 42 | \item{persisted_props}{List of a value equal to: 'on's. Properties whose user interactions will persist after refreshing the 43 | component or the page. Since only `on` is allowed this prop can 44 | normally be ignored.} 45 | 46 | \item{persistence}{Logical | character | numeric. Used to allow user interactions in this component to be persisted when 47 | the component - or the page - is refreshed. If `persisted` is truthy and 48 | hasn't changed from its previous value, a `value` that the user has 49 | changed while using the app will keep that change, as long as 50 | the new `value` also matches what was given originally. 51 | Used in conjunction with `persistence_type`.} 52 | 53 | \item{persistence_type}{A value equal to: 'local', 'session', 'memory'. Where persisted user changes will be stored: 54 | memory: only kept in memory, reset on page refresh. 55 | local: window.localStorage, data is kept after the browser quit. 56 | session: window.sessionStorage, data is cleared once the browser quit.} 57 | 58 | \item{size}{Numeric. The size (diameter) of the power button in pixels} 59 | 60 | \item{style}{Named list. Style to apply to the root component element.} 61 | 62 | \item{theme}{Named list. Theme configuration to be set by a ThemeProvider} 63 | } 64 | 65 | \value{named list of JSON elements corresponding to React.js properties and their values} 66 | 67 | -------------------------------------------------------------------------------- /man/daqPrecisionInput.Rd: -------------------------------------------------------------------------------- 1 | % Auto-generated: do not edit by hand 2 | \name{daqPrecisionInput} 3 | 4 | \alias{daqPrecisionInput} 5 | 6 | \title{PrecisionInput component} 7 | 8 | \description{ 9 | A numeric input component that converts an input value to the desired precision. 10 | } 11 | 12 | \usage{ 13 | daqPrecisionInput(id=NULL, className=NULL, disabled=NULL, label=NULL, 14 | labelPosition=NULL, max=NULL, min=NULL, 15 | persisted_props=NULL, persistence=NULL, 16 | persistence_type=NULL, precision=NULL, size=NULL, 17 | style=NULL, theme=NULL, value=NULL) 18 | } 19 | 20 | \arguments{ 21 | \item{id}{Character. The ID used to identify this compnent in Dash callbacks} 22 | 23 | \item{className}{Character. Class to apply to the root component element.} 24 | 25 | \item{disabled}{Logical. If true, numeric input cannot be changed.} 26 | 27 | \item{label}{Character | lists containing elements 'style', 'label'. 28 | those elements have the following types: 29 | - style (named list; optional) 30 | - label (character; optional). Description to be displayed alongside the scientific notation. To control styling, 31 | pass an object with label and style properties.} 32 | 33 | \item{labelPosition}{A value equal to: 'top', 'bottom'. Where the numeric input label is positioned.} 34 | 35 | \item{max}{Numeric. The maximum value of the numeric input} 36 | 37 | \item{min}{Numeric. The minimum value of the numeric input} 38 | 39 | \item{persisted_props}{List of a value equal to: 'value's. Properties whose user interactions will persist after refreshing the 40 | component or the page. Since only `value` is allowed this prop can 41 | normally be ignored.} 42 | 43 | \item{persistence}{Logical | character | numeric. Used to allow user interactions in this component to be persisted when 44 | the component - or the page - is refreshed. If `persisted` is truthy and 45 | hasn't changed from its previous value, a `value` that the user has 46 | changed while using the app will keep that change, as long as 47 | the new `value` also matches what was given originally. 48 | Used in conjunction with `persistence_type`.} 49 | 50 | \item{persistence_type}{A value equal to: 'local', 'session', 'memory'. Where persisted user changes will be stored: 51 | memory: only kept in memory, reset on page refresh. 52 | local: window.localStorage, data is kept after the browser quit. 53 | session: window.sessionStorage, data is cleared once the browser quit.} 54 | 55 | \item{precision}{Numeric. Number of significant figures} 56 | 57 | \item{size}{Numeric. The size (length) of the numeric input in pixels} 58 | 59 | \item{style}{Named list. Style to apply to the root component element.} 60 | 61 | \item{theme}{Named list. Theme configuration to be set by a ThemeProvider} 62 | 63 | \item{value}{Numeric. The value of numeric input} 64 | } 65 | 66 | \value{named list of JSON elements corresponding to React.js properties and their values} 67 | 68 | -------------------------------------------------------------------------------- /man/daqStopButton.Rd: -------------------------------------------------------------------------------- 1 | % Auto-generated: do not edit by hand 2 | \name{daqStopButton} 3 | 4 | \alias{daqStopButton} 5 | 6 | \title{StopButton component} 7 | 8 | \description{ 9 | A Stop button component 10 | } 11 | 12 | \usage{ 13 | daqStopButton(children=NULL, id=NULL, buttonText=NULL, className=NULL, 14 | disabled=NULL, label=NULL, labelPosition=NULL, 15 | n_clicks=NULL, size=NULL, style=NULL, theme=NULL) 16 | } 17 | 18 | \arguments{ 19 | \item{children}{A list of or a singular dash component, string or number. The children of the button.} 20 | 21 | \item{id}{Character. The ID used to identify this compnent in Dash callbacks} 22 | 23 | \item{buttonText}{Character. Text displayed in the button} 24 | 25 | \item{className}{Character. Class to apply to the root component element.} 26 | 27 | \item{disabled}{Logical. If true, button cannot be pressesd.} 28 | 29 | \item{label}{Character | lists containing elements 'style', 'label'. 30 | those elements have the following types: 31 | - style (named list; optional) 32 | - label (character; optional). Description to be displayed alongside the button. 33 | To control styling, pass an object with label and 34 | style properties.} 35 | 36 | \item{labelPosition}{A value equal to: 'top', 'bottom'. Where the label is positioned.} 37 | 38 | \item{n_clicks}{Numeric. Number of times the button was clicked} 39 | 40 | \item{size}{Numeric. The size (width) of the stop button in pixels} 41 | 42 | \item{style}{Named list. Style to apply to the root component element.} 43 | 44 | \item{theme}{Named list. Theme configuration to be set by a ThemeProvider} 45 | } 46 | 47 | \value{named list of JSON elements corresponding to React.js properties and their values} 48 | 49 | -------------------------------------------------------------------------------- /man/daqTank.Rd: -------------------------------------------------------------------------------- 1 | % Auto-generated: do not edit by hand 2 | \name{daqTank} 3 | 4 | \alias{daqTank} 5 | 6 | \title{Tank component} 7 | 8 | \description{ 9 | A Tank component that fills to a value between some range. 10 | } 11 | 12 | \usage{ 13 | daqTank(id=NULL, base=NULL, className=NULL, color=NULL, 14 | currentValueStyle=NULL, exceedMessage=NULL, height=NULL, 15 | label=NULL, labelPosition=NULL, lagingMessage=NULL, 16 | logarithmic=NULL, max=NULL, min=NULL, scale=NULL, 17 | showCurrentValue=NULL, style=NULL, textColor=NULL, 18 | theme=NULL, units=NULL, value=NULL, width=NULL) 19 | } 20 | 21 | \arguments{ 22 | \item{id}{Character. The ID used to identify this component in Dash callbacks} 23 | 24 | \item{base}{Numeric. Base to be used in logarithmic scale.} 25 | 26 | \item{className}{Character. Class to apply to the root component element.} 27 | 28 | \item{color}{Character. The color of tank fill} 29 | 30 | \item{currentValueStyle}{Named list. text style of current value} 31 | 32 | \item{exceedMessage}{Character. Warning message when value exceed max} 33 | 34 | \item{height}{Numeric. The height of the tank in pixels} 35 | 36 | \item{label}{Character | lists containing elements 'style', 'label'. 37 | those elements have the following types: 38 | - style (named list; optional) 39 | - label (character; optional). Description to be displayed alongside the control. To control styling, 40 | pass an object with label and style properties.} 41 | 42 | \item{labelPosition}{A value equal to: 'top', 'bottom'. Where the component label is positioned.} 43 | 44 | \item{lagingMessage}{Character. Warning message when value is laging from min} 45 | 46 | \item{logarithmic}{Logical. If set to true, a logarithmic scale will be 47 | used.} 48 | 49 | \item{max}{Numeric. The maximum value of the tank. If logarithmic, 50 | represents the maximum exponent.} 51 | 52 | \item{min}{Numeric. The minimum value of the tank. If logarithmic, 53 | represents minimum exponent.} 54 | 55 | \item{scale}{Lists containing elements 'start', 'interval', 'labelinterval', 'custom'. 56 | those elements have the following types: 57 | - start (numeric; optional): value to start the scale from. defaults 58 | to min. 59 | - interval (numeric; optional): interval by which the scale goes up. attempts 60 | to dynamically divide min-max range by 61 | default. 62 | - labelinterval (numeric; optional): interval by which labels are added to 63 | scale marks. defaults to 2 (every other 64 | mark has a label). 65 | - custom (optional): custom scale marks. the key determines the position 66 | and the value determines what will show. if you want 67 | to set the style of a specific mark point, the value 68 | should be an object which contains style and label 69 | properties. custom has the following type: numeric | lists containing elements 'style', 'label'. 70 | those elements have the following types: 71 | - style (character; optional) 72 | - label (character; optional). Configuration for the component scale.} 73 | 74 | \item{showCurrentValue}{Logical. If true, the current value of the tank 75 | will be displayed} 76 | 77 | \item{style}{Named list. Style to apply to the root component element.} 78 | 79 | \item{textColor}{Character. text color} 80 | 81 | \item{theme}{Named list. Theme configuration to be set by a ThemeProvider} 82 | 83 | \item{units}{Character. Label for the current value} 84 | 85 | \item{value}{Numeric. The value of tank. If logarithmic, the displayed value 86 | will be the logarithm of the inputted value.} 87 | 88 | \item{width}{Numeric. The width of the tank in pixels} 89 | } 90 | 91 | \value{named list of JSON elements corresponding to React.js properties and their values} 92 | 93 | -------------------------------------------------------------------------------- /man/daqThermometer.Rd: -------------------------------------------------------------------------------- 1 | % Auto-generated: do not edit by hand 2 | \name{daqThermometer} 3 | 4 | \alias{daqThermometer} 5 | 6 | \title{Thermometer component} 7 | 8 | \description{ 9 | A thermometer component that fills to a value between some range 10 | } 11 | 12 | \usage{ 13 | daqThermometer(id=NULL, base=NULL, className=NULL, color=NULL, height=NULL, 14 | label=NULL, labelPosition=NULL, logarithmic=NULL, max=NULL, 15 | min=NULL, scale=NULL, showCurrentValue=NULL, style=NULL, 16 | theme=NULL, units=NULL, value=NULL, width=NULL) 17 | } 18 | 19 | \arguments{ 20 | \item{id}{Character. The ID used to identify this compnent in Dash callbacks} 21 | 22 | \item{base}{Numeric. Base to be used in logarithmic scale.} 23 | 24 | \item{className}{Character. Class to apply to the root component element.} 25 | 26 | \item{color}{Character. The color of the thermometer fill/current value text} 27 | 28 | \item{height}{Numeric. The height of the thermometer in pixels} 29 | 30 | \item{label}{Character | lists containing elements 'style', 'label'. 31 | those elements have the following types: 32 | - style (named list; optional) 33 | - label (character; optional). Description to be displayed alongside the control. To control styling, pass an object with label and style properties.} 34 | 35 | \item{labelPosition}{A value equal to: 'top', 'bottom'. Where the component label is positioned.} 36 | 37 | \item{logarithmic}{Logical. If set to true, a logarithmic scale will be 38 | used.} 39 | 40 | \item{max}{Numeric. The maximum value of the thermometer. If logarithmic, 41 | represents the maximum exponent.} 42 | 43 | \item{min}{Numeric. The minimum value of the thermometer. If logarithmic, 44 | represents the minimum exponent.} 45 | 46 | \item{scale}{Lists containing elements 'start', 'interval', 'labelinterval', 'custom'. 47 | those elements have the following types: 48 | - start (numeric; optional): value to start the scale from. defaults 49 | to min. 50 | - interval (numeric; optional): interval by which the scale goes up. attempts 51 | to dynamically divide min-max range by 52 | default. 53 | - labelinterval (numeric; optional): interval by which labels are added to 54 | scale marks. defaults to 2 (every other 55 | mark has a label). 56 | - custom (optional): custom scale marks. the key determines the position 57 | and the value determines what will show. if you want 58 | to set the style of a specific mark point, the value 59 | should be an object which contains style and label 60 | properties. custom has the following type: numeric | lists containing elements 'style', 'label'. 61 | those elements have the following types: 62 | - style (character; optional) 63 | - label (character; optional). Configuration for the component scale.} 64 | 65 | \item{showCurrentValue}{Logical. If true, the current value of the 66 | thermometer will be displayed} 67 | 68 | \item{style}{Named list. Style to apply to the root component element.} 69 | 70 | \item{theme}{Named list. Theme configuration to be set by a ThemeProvider} 71 | 72 | \item{units}{Character. Label for the current value} 73 | 74 | \item{value}{Numeric. The value of thermometer. If logarthmic, the value 75 | displayed will be the logarithm of the inputted value.} 76 | 77 | \item{width}{Numeric. The width of the thermometer in pixels} 78 | } 79 | 80 | \value{named list of JSON elements corresponding to React.js properties and their values} 81 | 82 | -------------------------------------------------------------------------------- /man/daqToggleSwitch.Rd: -------------------------------------------------------------------------------- 1 | % Auto-generated: do not edit by hand 2 | \name{daqToggleSwitch} 3 | 4 | \alias{daqToggleSwitch} 5 | 6 | \title{ToggleSwitch component} 7 | 8 | \description{ 9 | A switch component that toggles between two values. 10 | } 11 | 12 | \usage{ 13 | daqToggleSwitch(id=NULL, className=NULL, color=NULL, disabled=NULL, 14 | label=NULL, labelPosition=NULL, persisted_props=NULL, 15 | persistence=NULL, persistence_type=NULL, size=NULL, 16 | style=NULL, theme=NULL, value=NULL, vertical=NULL) 17 | } 18 | 19 | \arguments{ 20 | \item{id}{Character. The ID used to identify this compnent in Dash callbacks} 21 | 22 | \item{className}{Character. Class to apply to the root component element.} 23 | 24 | \item{color}{Character. Color to highlight button/indicator} 25 | 26 | \item{disabled}{Logical. If true, switch cannot be clicked} 27 | 28 | \item{label}{Character | lists containing elements 'style', 'label'. 29 | those elements have the following types: 30 | - style (named list; optional) 31 | - label (character; optional) | list of character | lists containing elements 'style', 'label'. 32 | those elements have the following types: 33 | - style (named list; optional) 34 | - label (character; optional)s. Description to be displayed alongside the control. To control styling, pass an object with label and style properties.} 35 | 36 | \item{labelPosition}{A value equal to: 'top', 'bottom'. Where the component label is positioned.} 37 | 38 | \item{persisted_props}{List of a value equal to: 'value's. Properties whose user interactions will persist after refreshing the 39 | component or the page. Since only `value` is allowed this prop can 40 | normally be ignored.} 41 | 42 | \item{persistence}{Logical | character | numeric. Used to allow user interactions in this component to be persisted when 43 | the component - or the page - is refreshed. If `persisted` is truthy and 44 | hasn't changed from its previous value, a `value` that the user has 45 | changed while using the app will keep that change, as long as 46 | the new `value` also matches what was given originally. 47 | Used in conjunction with `persistence_type`.} 48 | 49 | \item{persistence_type}{A value equal to: 'local', 'session', 'memory'. Where persisted user changes will be stored: 50 | memory: only kept in memory, reset on page refresh. 51 | local: window.localStorage, data is kept after the browser quit. 52 | session: window.sessionStorage, data is cleared once the browser quit.} 53 | 54 | \item{size}{Numeric. The size of the switch} 55 | 56 | \item{style}{Named list. Style to apply to the root object.} 57 | 58 | \item{theme}{Named list. Theme configuration to be set by a ThemeProvider} 59 | 60 | \item{value}{Logical. The state of the switch} 61 | 62 | \item{vertical}{Logical. If true, switch will be vertical instead 63 | of horizontal} 64 | } 65 | 66 | \value{named list of JSON elements corresponding to React.js properties and their values} 67 | 68 | -------------------------------------------------------------------------------- /man/dashDaq-package.Rd: -------------------------------------------------------------------------------- 1 | % Auto-generated: do not edit by hand 2 | \docType{package} 3 | \name{dashDaq-package} 4 | \alias{dashDaq} 5 | \title{Interactive Data Acquisition and Control Components for Dash } 6 | \description{ 7 | A robust set of controls that make it simpler to integrate data acquisition and controls into your Dash applications. 8 | } 9 | \author{ 10 | \strong{Maintainer}: Ryan Patrick Kyle 11 | } 12 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "dash-daq", 3 | "version": "0.6.0", 4 | "engines": { 5 | "node": ">=8" 6 | }, 7 | "description": "DAQ components for Dash", 8 | "repository": { 9 | "type": "git", 10 | "url": "git://github.com/plotly/dash-daq.git" 11 | }, 12 | "bugs": { 13 | "url": "https://github.com/plotly/dash-daq/issues" 14 | }, 15 | "homepage": "https://github.com/plotly/dash-daq", 16 | "main": "dash_daq/dash_daq.min.js", 17 | "author": "The Plotly Team ", 18 | "maintainer": "The Plotly Team ", 19 | "license": "MIT", 20 | "scripts": { 21 | "copy-lib": "copyfiles -u 1 lib/* dash_daq", 22 | "dash-demo": "python demo.py", 23 | "install-local": "pip install -e .", 24 | "lint": "eslint --fix --ignore-path .eslintignore src/", 25 | "start": "npm run build:dev", 26 | "build:js": "webpack --mode production", 27 | "build:js-dev": "webpack --mode development", 28 | "build:py": "python get_version_info.py && yarn copy-lib && dash-generate-components ./src/components dash_daq -p package-info.json", 29 | "build:r": "dash-generate-components ./src/components dash_daq -p package-info.json --r-prefix='daq'", 30 | "build": "npm run test && npm run lint && npm run build:js && npm run build:py && npm run build:r", 31 | "postbuild": "es-check es5 dash_daq/*.js", 32 | "build:dev": "npm run build:js-dev && npm run build:py", 33 | "build-tarball": "npm run build && python setup.py sdist", 34 | "test": "jest src/components/__tests__", 35 | "test-gauge": "jest src/components/__tests__/Gauge.test.js", 36 | "test:frontend-cov": "jest --coverage --silent", 37 | "test:watch": "jest --watch", 38 | "uninstall-local": "pip uninstall dash_daq -y", 39 | "prettier": "yarn prettier-src && yarn prettier-tests", 40 | "prettier-src": "prettier --single-quote --print-width=100 --write src/**/*.js", 41 | "prettier-tests": "prettier --single-quote --print-width=100 --write src/components/__tests__/**/*.js", 42 | "prettier-restage": "git update-index --again" 43 | }, 44 | "dependencies": { 45 | "color": "^3.0.0", 46 | "conic-gradient": "^1.0.0", 47 | "copyfiles": "^1.2.0", 48 | "dash-components-archetype": "^0.2.11", 49 | "deep-equal": "^1.0.1", 50 | "nipplejs": "^0.7.1", 51 | "prop-types": "^15.5.9", 52 | "ramda": "^0.25.0", 53 | "rc-slider": "^9.1.0", 54 | "react": "16.13.0", 55 | "react-color": "^2.18.0", 56 | "react-dom": "16.13.0", 57 | "react-numeric-input": "^2.2.3", 58 | "styled-components": "^4.4.0", 59 | "tinygradient": "^0.4.0", 60 | "webpack": "^4.41.0", 61 | "yarn": "^1.22.11" 62 | }, 63 | "devDependencies": { 64 | "@babel/core": "^7.6.0", 65 | "@babel/plugin-syntax-dynamic-import": "^7.2.0", 66 | "@babel/preset-env": "^7.6.0", 67 | "@babel/preset-react": "^7.0.0", 68 | "@plotly/webpack-dash-dynamic-import": "^1.1.4", 69 | "babel-eslint": "^10.0.3", 70 | "babel-loader": "^8.0.6", 71 | "chalk": "^2.3.1", 72 | "css-loader": "^3.4.2", 73 | "dash-components-archetype-dev": "^0.2.11", 74 | "enzyme": "^3.10.0", 75 | "enzyme-adapter-react-16": "^1.14.0", 76 | "es-check": "^5.0.0", 77 | "fs-extra": "^5.0.0", 78 | "identity-obj-proxy": "^3.0.0", 79 | "jest": "^24.9.0", 80 | "jest-canvas-mock": "^2.1.1", 81 | "pre-commit": "^1.2.2", 82 | "prettier": "^1.10.2", 83 | "react-docgen": "^3.0.0", 84 | "react-docgen-markdown-renderer": "^1.0.2", 85 | "react-test-renderer": "^16.8.6", 86 | "sinon": "^4.3.0", 87 | "style-loader": "^1.1.3", 88 | "webpack-cli": "^3.3.9" 89 | }, 90 | "jest": { 91 | "coveragePathIgnorePatterns": [ 92 | "/src/styled", 93 | "/src/helpers" 94 | ], 95 | "testURL": "http://localhost", 96 | "setupFiles": [ 97 | "jest-canvas-mock" 98 | ], 99 | "moduleNameMapper": { 100 | "\\.css": "identity-obj-proxy" 101 | } 102 | }, 103 | "files": [ 104 | "dash_daq/*{.js,.map}" 105 | ], 106 | "pre-commit": [ 107 | "test", 108 | "prettier", 109 | "prettier-restage" 110 | ], 111 | "keywords": [ 112 | "dash", 113 | "daq", 114 | "components" 115 | ] 116 | } 117 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | --index-url https://pypi.python.org/simple/ 2 | 3 | -e . 4 | dash>=1.6.0 5 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | import json 2 | import os 3 | from setuptools import setup 4 | from io import open 5 | 6 | filepath = os.path.join(os.path.abspath(os.path.dirname(__file__)), 'README.md') 7 | with open(filepath, encoding='utf-8') as f: 8 | long_description = f.read() 9 | 10 | with open(os.path.join('dash_daq', 'package-info.json'), encoding='utf-8') as f: 11 | package = json.load(f) 12 | 13 | package_name = package["name"].replace(" ", "_").replace("-", "_") 14 | 15 | setup( 16 | name=package_name, 17 | version=package["version"], 18 | url='http://github.com/plotly/{}'.format(package_name.replace('_', '-')), 19 | author=package['author'], 20 | author_email='dashdaq@plotly.com', 21 | packages=[package_name], 22 | include_package_data=True, 23 | description=package['description'] if 'description' in package else package_name, 24 | long_description=long_description, 25 | long_description_content_type='text/markdown', 26 | install_requires=[ 27 | 'dash>=1.6.1' 28 | ], 29 | classifiers=[ 30 | "Programming Language :: Python :: 3", 31 | "License :: OSI Approved :: MIT License", 32 | "Operating System :: OS Independent", 33 | ], 34 | ) 35 | -------------------------------------------------------------------------------- /src/components/ColorPicker.react.js: -------------------------------------------------------------------------------- 1 | import PropTypes from 'prop-types'; 2 | import React, { Component, lazy, Suspense } from 'react'; 3 | 4 | import { light } from '../styled/constants'; 5 | 6 | const RealColorPicker = lazy(() => 7 | import(/* webpackChunkName: "colorpicker" */ '../fragments/ColorPicker.react') 8 | ); 9 | /** 10 | * A color picker. 11 | */ 12 | export default class ColorPicker extends Component { 13 | render() { 14 | return ( 15 | 16 | 17 | 18 | ); 19 | } 20 | } 21 | 22 | ColorPicker.defaultProps = { 23 | size: 225, 24 | theme: light, 25 | labelPosition: 'top', 26 | persisted_props: ['value'], 27 | persistence_type: 'local' 28 | }; 29 | 30 | ColorPicker.propTypes = { 31 | /** 32 | * The ID used to identify the color picker in Dash callbacks 33 | */ 34 | id: PropTypes.string, 35 | 36 | /** 37 | * Color value of the picker 38 | */ 39 | value: PropTypes.shape({ 40 | /** 41 | * Hex string 42 | */ 43 | hex: PropTypes.string, 44 | 45 | /** 46 | * RGB/RGBA object 47 | */ 48 | rbg: PropTypes.shape({ 49 | r: PropTypes.number, 50 | g: PropTypes.number, 51 | b: PropTypes.number, 52 | a: PropTypes.number 53 | }) 54 | }), 55 | 56 | /** 57 | * If true, color cannot be picked. 58 | */ 59 | disabled: PropTypes.bool, 60 | 61 | /** 62 | * Size (width) of the component in pixels 63 | */ 64 | size: PropTypes.number, 65 | 66 | /** 67 | * Theme configuration to be set by a ThemeProvider 68 | */ 69 | theme: PropTypes.object, 70 | 71 | /** 72 | * Description to be displayed alongside the control. To control styling, 73 | * pass an object with label and style properties 74 | */ 75 | label: PropTypes.oneOfType([ 76 | /** 77 | * Label to be displayed 78 | */ 79 | PropTypes.string, 80 | 81 | /** 82 | * The style and label 83 | */ 84 | PropTypes.shape({ 85 | style: PropTypes.object, 86 | label: PropTypes.string 87 | }) 88 | ]), 89 | 90 | /** 91 | * Where the indicator label is positioned 92 | */ 93 | labelPosition: PropTypes.oneOf(['top', 'bottom']), 94 | 95 | /** 96 | * Class to apply to the root component element 97 | */ 98 | className: PropTypes.string, 99 | 100 | /** 101 | * Dash-assigned callback that gets fired when 102 | * the color picker's value changes 103 | */ 104 | setProps: PropTypes.func, 105 | 106 | /** 107 | * Style to apply to the root component element 108 | */ 109 | style: PropTypes.object, 110 | 111 | /** 112 | * Used to allow user interactions in this component to be persisted when 113 | * the component - or the page - is refreshed. If `persisted` is truthy and 114 | * hasn't changed from its previous value, a `value` that the user has 115 | * changed while using the app will keep that change, as long as 116 | * the new `value` also matches what was given originally. 117 | * Used in conjunction with `persistence_type`. 118 | */ 119 | persistence: PropTypes.oneOfType([PropTypes.bool, PropTypes.string, PropTypes.number]), 120 | 121 | /** 122 | * Properties whose user interactions will persist after refreshing the 123 | * component or the page. Since only `value` is allowed this prop can 124 | * normally be ignored. 125 | */ 126 | persisted_props: PropTypes.arrayOf(PropTypes.oneOf(['value'])), 127 | 128 | /** 129 | * Where persisted user changes will be stored: 130 | * memory: only kept in memory, reset on page refresh. 131 | * local: window.localStorage, data is kept after the browser quit. 132 | * session: window.sessionStorage, data is cleared once the browser quit. 133 | */ 134 | persistence_type: PropTypes.oneOf(['local', 'session', 'memory']) 135 | }; 136 | 137 | export const defaultProps = ColorPicker.defaultProps; 138 | export const propTypes = ColorPicker.propTypes; 139 | -------------------------------------------------------------------------------- /src/components/DarkThemeProvider.react.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | 4 | import { ThemeProvider } from 'styled-components'; 5 | import { dark } from '../styled/constants'; 6 | 7 | /** 8 | * DarkThemeProvider is a component that is placed at the root of 9 | * the component tree to make all components match the dark theme 10 | */ 11 | function DarkThemeProvider(props) { 12 | return ( 13 | 14 |
{props.children}
15 |
16 | ); 17 | } 18 | 19 | DarkThemeProvider.propTypes = { 20 | /** 21 | * The children of this component 22 | */ 23 | children: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.node), PropTypes.node]), 24 | 25 | /** 26 | * Theme object to override with a custom theme 27 | */ 28 | theme: PropTypes.shape({ 29 | /** 30 | * Highlight color 31 | */ 32 | primary: PropTypes.string, 33 | /** 34 | * Supporting color 35 | */ 36 | secondary: PropTypes.string, 37 | /** 38 | * Color used for UI details, like borders 39 | */ 40 | detail: PropTypes.string, 41 | /** 42 | * True for Dark mode, false for Light 43 | */ 44 | dark: PropTypes.bool 45 | }) 46 | }; 47 | 48 | export default DarkThemeProvider; 49 | -------------------------------------------------------------------------------- /src/components/Indicator.react.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import convertColor from 'color'; 4 | import { withTheme } from 'styled-components'; 5 | 6 | import IndicatorLight from '../styled/shared/Indicator.styled'; 7 | 8 | import LabelContainer from '../styled/shared/LabelContainer.styled'; 9 | 10 | import { colors, light } from '../styled/constants'; 11 | 12 | import { getClassName, getFilteredProps } from '../helpers/classNameGenerator'; 13 | 14 | /** 15 | * A boolean indicator LED. 16 | */ 17 | const Indicator = props => { 18 | const { id, className, color, size, width, height, value, style, theme } = props; 19 | 20 | const bg = convertColor(color) 21 | .desaturate(0.2) 22 | .lighten(0.2) 23 | .rgb() 24 | .toString(); 25 | 26 | const elementName = getClassName('indicator', theme); 27 | const filteredProps = getFilteredProps(props); 28 | 29 | return ( 30 |
31 | 32 | 43 | 44 |
45 | ); 46 | }; 47 | 48 | Indicator.defaultProps = { 49 | color: colors.DARKER_PRIMARY, 50 | size: 15, 51 | theme: light, 52 | labelPosition: 'top' 53 | }; 54 | 55 | Indicator.propTypes = { 56 | /** 57 | * The ID used to identify the indicator in Dash callbacks 58 | */ 59 | id: PropTypes.string, 60 | 61 | /** 62 | * If true, indicator is illuminated 63 | */ 64 | value: PropTypes.bool, 65 | 66 | /** 67 | * Color of the indicator 68 | */ 69 | color: PropTypes.string, 70 | 71 | /** 72 | * Size of the component. Either use this or width and height 73 | */ 74 | size: PropTypes.number, 75 | 76 | /** 77 | * Width of the component. Set both width and height for a rectangular indicator 78 | */ 79 | width: PropTypes.number, 80 | 81 | /** 82 | * Height of the component. Set both width and height for a rectangular indicator 83 | */ 84 | height: PropTypes.number, 85 | 86 | /** 87 | * Theme configuration to be set by a ThemeProvider 88 | */ 89 | theme: PropTypes.object, 90 | 91 | /** 92 | * Description to be displayed alongside the control. To control styling, 93 | * pass an object with label and style properties 94 | */ 95 | label: PropTypes.oneOfType([ 96 | /** 97 | * Label to be displayed 98 | */ 99 | PropTypes.string, 100 | 101 | /** 102 | * The style and label 103 | */ 104 | PropTypes.shape({ 105 | style: PropTypes.object, 106 | label: PropTypes.string 107 | }) 108 | ]), 109 | 110 | /** 111 | * Where the indicator label is positioned 112 | */ 113 | labelPosition: PropTypes.oneOf(['top', 'bottom', 'right', 'left']), 114 | 115 | /** 116 | * Class to apply to the root component element 117 | */ 118 | className: PropTypes.string, 119 | 120 | /** 121 | * Style to apply to the root component element 122 | */ 123 | style: PropTypes.object 124 | }; 125 | 126 | export default withTheme(Indicator); 127 | -------------------------------------------------------------------------------- /src/components/Joystick.react.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import { withTheme } from 'styled-components'; 4 | import joystick from 'nipplejs'; 5 | 6 | import { light } from '../styled/constants'; 7 | import LabelContainer from '../styled/shared/LabelContainer.styled'; 8 | 9 | import { getClassName, getFilteredProps } from '../helpers/classNameGenerator'; 10 | 11 | /** 12 | * A joystick. 13 | */ 14 | class Joystick extends Component { 15 | constructor(props) { 16 | super(props); 17 | this.lastAngle = 0; 18 | } 19 | 20 | componentDidMount() { 21 | const { size, setProps } = this.props; 22 | this.manager = joystick.create({ 23 | mode: 'static', 24 | color: 'grey', 25 | size: size, 26 | position: { left: '50%', top: '50%' }, 27 | zone: this.zoneRef 28 | }); 29 | this.manager.on('move', (e, data) => { 30 | const { 31 | angle: { degree }, 32 | force 33 | } = data; 34 | this.lastAngle = degree; 35 | if (setProps) { 36 | setProps({ 37 | angle: degree, 38 | force 39 | }); 40 | } 41 | }); 42 | this.manager.on('end', () => { 43 | if (setProps) { 44 | setProps({ 45 | angle: this.lastAngle, 46 | force: 0 47 | }); 48 | } 49 | }); 50 | } 51 | 52 | componentWillUnmount() { 53 | this.manager.destroy(); 54 | } 55 | 56 | render() { 57 | const { id, className, style, size, theme } = this.props; 58 | 59 | const elementName = getClassName('joystick', theme); 60 | const filteredProps = getFilteredProps(this.props); 61 | 62 | return ( 63 |
64 | 65 |
(this.zoneRef = ref)} 68 | style={{ 69 | position: 'relative', 70 | width: size + 'px', 71 | height: size + 'px' 72 | }} 73 | /> 74 | 75 |
76 | ); 77 | } 78 | } 79 | 80 | Joystick.defaultProps = { 81 | size: 100, 82 | theme: light, 83 | labelPosition: 'top' 84 | }; 85 | 86 | Joystick.propTypes = { 87 | /** 88 | * The ID used to identify the Joystick in Dash callbacks 89 | */ 90 | id: PropTypes.string, 91 | 92 | /** 93 | * Joystick angle in degrees, 0 = right, 90 = up, 180 = left, 270 = down 94 | */ 95 | angle: PropTypes.number, 96 | 97 | /** 98 | * Joystick force: distance between cursor and center in big-circle radii 99 | */ 100 | force: PropTypes.number, 101 | 102 | /** 103 | * Size (width) of the component in pixels 104 | */ 105 | size: PropTypes.number, 106 | 107 | /** 108 | * Theme configuration to be set by a ThemeProvider 109 | */ 110 | theme: PropTypes.object, 111 | 112 | /** 113 | * Description to be displayed alongside the control. To control styling, 114 | * pass an object with label and style properties 115 | */ 116 | label: PropTypes.oneOfType([ 117 | /** 118 | * Label to be displayed 119 | */ 120 | PropTypes.string, 121 | 122 | /** 123 | * The style and label 124 | */ 125 | PropTypes.shape({ 126 | style: PropTypes.object, 127 | label: PropTypes.string 128 | }) 129 | ]), 130 | 131 | /** 132 | * Where the indicator label is positioned 133 | */ 134 | labelPosition: PropTypes.oneOf(['top', 'bottom']), 135 | 136 | /** 137 | * Class to apply to the root component element 138 | */ 139 | className: PropTypes.string, 140 | 141 | /** 142 | * Dash-assigned callback that gets fired when 143 | * the color picker's value changes 144 | */ 145 | setProps: PropTypes.func, 146 | 147 | /** 148 | * Style to apply to the root component element 149 | */ 150 | style: PropTypes.object 151 | }; 152 | 153 | export default withTheme(Joystick); 154 | -------------------------------------------------------------------------------- /src/components/StopButton.react.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import { withTheme } from 'styled-components'; 4 | 5 | import { Button } from '../styled/StopButton.styled'; 6 | import LabelContainer from '../styled/shared/LabelContainer.styled'; 7 | 8 | import { getClassName, getFilteredProps } from '../helpers/classNameGenerator'; 9 | 10 | /** 11 | * A Stop button component 12 | */ 13 | const StopButton = props => { 14 | const { id, className, style, size, disabled, children, n_clicks, buttonText, theme } = props; 15 | 16 | const elementName = getClassName('stopbutton', theme); 17 | const filteredProps = getFilteredProps(props); 18 | 19 | return ( 20 |
21 | 22 | 32 | 33 |
34 | ); 35 | }; 36 | 37 | StopButton.defaultProps = { 38 | buttonText: 'Stop', 39 | n_clicks: 0, 40 | size: 92, 41 | labelPosition: 'top' 42 | }; 43 | 44 | StopButton.propTypes = { 45 | /** 46 | * The ID used to identify this compnent in Dash callbacks 47 | */ 48 | id: PropTypes.string, 49 | 50 | /** 51 | * The size (width) of the stop button in pixels 52 | */ 53 | size: PropTypes.number, 54 | 55 | /** 56 | * Text displayed in the button 57 | */ 58 | buttonText: PropTypes.string, 59 | 60 | /** 61 | * Number of times the button was clicked 62 | */ 63 | n_clicks: PropTypes.number, 64 | 65 | /** 66 | * If true, button cannot be pressesd. 67 | */ 68 | disabled: PropTypes.bool, 69 | 70 | /** 71 | * The children of the button. 72 | */ 73 | children: PropTypes.node, 74 | 75 | /** 76 | * Theme configuration to be set by a ThemeProvider 77 | */ 78 | theme: PropTypes.object, 79 | 80 | /** 81 | * Description to be displayed alongside the button. 82 | * To control styling, pass an object with label and 83 | * style properties. 84 | */ 85 | label: PropTypes.oneOfType([ 86 | /** 87 | * Label to be displayed 88 | */ 89 | PropTypes.string, 90 | 91 | /** 92 | * The style and label 93 | */ 94 | PropTypes.shape({ 95 | style: PropTypes.object, 96 | label: PropTypes.string 97 | }) 98 | ]), 99 | 100 | /** 101 | * Where the label is positioned. 102 | */ 103 | labelPosition: PropTypes.oneOf(['top', 'bottom']), 104 | 105 | /** 106 | * Class to apply to the root component element. 107 | */ 108 | className: PropTypes.string, 109 | 110 | /** 111 | * Style to apply to the root component element. 112 | */ 113 | style: PropTypes.object, 114 | 115 | /** 116 | * Dash-assigned callback that gets fired when the 117 | * button is clicked. 118 | */ 119 | setProps: PropTypes.func 120 | }; 121 | 122 | export default withTheme(StopButton); 123 | -------------------------------------------------------------------------------- /src/components/__tests__/.eslintrc: -------------------------------------------------------------------------------- 1 | --- 2 | extends: ../../../node_modules/dash-components-archetype/config/eslint/eslintrc-test.json 3 | 4 | globals: 5 | expect: false 6 | -------------------------------------------------------------------------------- /src/components/__tests__/BooleanSwitch.test.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | import React from 'react'; 3 | import Enzyme from 'enzyme'; 4 | import Adapter from 'enzyme-adapter-react-16'; 5 | Enzyme.configure({ adapter: new Adapter() }); 6 | 7 | import { shallow, mount } from 'enzyme'; 8 | import sinon from 'sinon'; 9 | 10 | import BooleanSwitch from '../BooleanSwitch.react'; 11 | import Indicator from '../../styled/shared/Indicator.styled'; 12 | import { Wrapper, ButtonContainer, Button } from '../../styled/ToggleSwitch.styled'; 13 | import Label from '../../styled/shared/Label.styled'; 14 | import { dark } from '../../styled/constants'; 15 | 16 | describe('Boolean Switch', () => { 17 | it('renders', () => { 18 | const component = shallow(); 19 | expect(component).toBeTruthy(); 20 | }); 21 | 22 | it('renders dark theme', () => { 23 | const component = mount(); 24 | expect(component).toBeTruthy(); 25 | }); 26 | 27 | it('renders vertically if desired', () => { 28 | const component = mount(); 29 | expect(component.find(Wrapper).prop('rotate')).toBe(-90); 30 | }); 31 | 32 | it('calls setProps on click', () => { 33 | const setProps = sinon.spy(); 34 | const component = mount(); 35 | 36 | component.find('button').simulate('click'); 37 | 38 | expect(setProps.calledOnce).toBeTruthy(); 39 | expect(setProps.getCall(0).args[0].on).toBeTruthy(); 40 | }); 41 | 42 | it('does not change props when disabled and clicked', () => { 43 | const setProps = sinon.spy(); 44 | const component = mount(); 45 | expect(component.prop('on')).toBeFalsy(); 46 | 47 | component.find('button').simulate('click'); 48 | 49 | expect(component.prop('on')).toBeFalsy(); 50 | }); 51 | 52 | it('does not fire click event when disabled and clicked', () => { 53 | const eventReciever = sinon.spy(); 54 | const component = mount(); 55 | 56 | component.find('button').simulate('click'); 57 | 58 | expect(eventReciever.calledOnce).toBeFalsy(); 59 | }); 60 | 61 | it('handles absent setProps callbacks', () => { 62 | const component = mount(); 63 | 64 | component.find('button').simulate('click'); 65 | }); 66 | 67 | it('updates on when props change', () => { 68 | const component = mount(); 69 | expect(component.prop('on')).toBeFalsy(); 70 | 71 | component.setProps({ on: true }); 72 | expect(component.prop('on')).toBeTruthy(); 73 | }); 74 | 75 | it('does not update on when props change without on set', () => { 76 | const component = mount(shallow().get(0)); 77 | 78 | component.setProps(); 79 | expect(component.state('on')).toBeTruthy(); 80 | }); 81 | 82 | it('has assigned className', () => { 83 | const component = shallow(); 84 | expect(component.render().hasClass('testClass')).toBeTruthy(); 85 | }); 86 | 87 | it('has assigned styles', () => { 88 | const style = { width: '600px' }; 89 | const component = shallow(); 90 | 91 | expect(component.render().prop('style')['width']).toBe(style['width']); 92 | }); 93 | 94 | it('has assigned id', () => { 95 | const component = shallow(); 96 | 97 | expect(component.render().prop('id')).toBe('testId'); 98 | }); 99 | 100 | it('positions label correctly', () => { 101 | const component = mount(); 102 | expect(component.find(Label).prop('position')).toBe('bottom'); 103 | }); 104 | 105 | it('displays indicators if desired', () => { 106 | const component = mount(); 107 | component.find(Indicator).forEach((node, index) => { 108 | if (index === 0) expect(node.prop('on')).toBeTruthy(); 109 | if (index === 1) expect(node.prop('on')).toBeTruthy(); // TODO: update when indicator API changed 110 | }); 111 | }); 112 | }); 113 | -------------------------------------------------------------------------------- /src/components/__tests__/ColorPicker.test.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | import React from 'react'; 3 | import Enzyme from 'enzyme'; 4 | import Adapter from 'enzyme-adapter-react-16'; 5 | Enzyme.configure({ adapter: new Adapter() }); 6 | 7 | import { shallow, mount } from 'enzyme'; 8 | import sinon from 'sinon'; 9 | 10 | import ColorPicker from '../../fragments/ColorPicker.react'; 11 | import Indicator from '../../styled/shared/Indicator.styled'; 12 | import { Wrapper, ButtonContainer, Button } from '../../styled/ToggleSwitch.styled'; 13 | import Label from '../../styled/shared/Label.styled'; 14 | import { dark } from '../../styled/constants'; 15 | 16 | describe('Color Picker', () => { 17 | it('renders', () => { 18 | const component = shallow(); 19 | expect(component).toBeTruthy(); 20 | }); 21 | 22 | it('renders dark theme', () => { 23 | const component = mount(); 24 | expect(component).toBeTruthy(); 25 | }); 26 | 27 | it('handles hex value', () => { 28 | const component = mount(shallow().get(0)); 29 | expect(component.state('value')).toEqual({ hex: '#ffffff' }); 30 | }); 31 | 32 | it('handles rgba value', () => { 33 | const component = mount( 34 | shallow().get(0) 35 | ); 36 | expect(component.state('value')).toEqual({ rgb: { r: 50, g: 100, b: 150, a: 0.8 } }); 37 | }); 38 | 39 | it('calls setProps callbacks', () => { 40 | const setProps = sinon.spy(); 41 | const component = mount(shallow().get(0)); 42 | 43 | component.instance().setValue({ hex: '#ffffff', rgb: '_' }); 44 | expect(setProps.calledOnce).toBeTruthy(); 45 | }); 46 | 47 | it('handles absent setProps callbacks', () => { 48 | const component = mount(shallow().get(0)); 49 | 50 | component.instance().setValue({ hex: '#ffffff', rgb: '_' }); 51 | expect(component).toBeTruthy(); 52 | }); 53 | 54 | it('does not explode when value set to null', () => { 55 | const component = mount(shallow().get(0)); 56 | 57 | component.instance().setValue(null); 58 | expect(component).toBeTruthy(); 59 | }); 60 | 61 | it('updates when props change', () => { 62 | const component = mount(shallow().get(0)); 63 | const oldColor = component.state('value'); 64 | 65 | component.setProps({ value: { hex: '#000000' } }); 66 | 67 | expect(component.render().prop('value')).not.toBe(oldColor); 68 | }); 69 | 70 | it('does not update on when props change without on set', () => { 71 | const component = mount(shallow().get(0)); 72 | 73 | component.setProps(); 74 | expect(component.state('value')).toEqual({ hex: '#ffffff' }); 75 | }); 76 | 77 | it('has assigned className', () => { 78 | const component = shallow(); 79 | expect(component.render().hasClass('testClass')).toBeTruthy(); 80 | }); 81 | 82 | it('has assigned styles', () => { 83 | const style = { width: '600px' }; 84 | const component = shallow(); 85 | 86 | expect(component.render().prop('style')['width']).toBe(style['width']); 87 | }); 88 | 89 | it('has assigned id', () => { 90 | const component = shallow(); 91 | 92 | expect(component.render().prop('id')).toBe('testId'); 93 | }); 94 | 95 | it('positions label correctly', () => { 96 | const component = mount(); 97 | expect(component.find(Label).prop('position')).toBe('bottom'); 98 | }); 99 | }); 100 | -------------------------------------------------------------------------------- /src/components/__tests__/GraduatedBar.test.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | import React from 'react'; 3 | import Enzyme from 'enzyme'; 4 | import Adapter from 'enzyme-adapter-react-16'; 5 | Enzyme.configure({ adapter: new Adapter() }); 6 | 7 | import { mount, shallow } from 'enzyme'; 8 | 9 | import GraduatedBar from '../GraduatedBar.react'; 10 | import { Container, Block, Value } from '../../styled/GraduatedBar.styled'; 11 | import Label from '../../styled/shared/Label.styled'; 12 | import DarkThemeProvider from '../DarkThemeProvider.react'; 13 | import { light } from '../../styled/constants'; 14 | 15 | describe('Graduated Bar', () => { 16 | it('renders', () => { 17 | const component = mount(); 18 | expect(component).toBeTruthy(); 19 | }); 20 | 21 | it('renders dark theme', () => { 22 | const component = mount( 23 | 24 | 25 | 26 | ); 27 | expect(component).toBeTruthy(); 28 | }); 29 | 30 | it('renders with non finite percentage', () => { 31 | const component = mount(); 32 | expect(component).toBeTruthy(); 33 | }); 34 | 35 | it('renders correct amount of blocks', () => { 36 | const component = mount(); 37 | expect(component.find(Block)).toHaveLength(49); 38 | }); 39 | 40 | it('shows current value if set', () => { 41 | const component = mount(shallow().get(0)); 42 | 43 | const currValue = component.find(Value); 44 | expect(currValue).toHaveLength(1); 45 | expect(currValue.text()).toBe('50%'); 46 | }); 47 | 48 | it('does not show current value if not set', () => { 49 | const component = mount(shallow().get(0)); 50 | 51 | expect(component.find(Value).hostNodes()).toHaveLength(0); 52 | }); 53 | 54 | it('handles color scale correctly', () => { 55 | const colors = { ranges: { red: [0, 5], blue: [5, 10] } }; 56 | const hasCustomColor = block => block.prop('color') !== light.primary; 57 | 58 | const component = mount( 59 | shallow().get(0) 60 | ); 61 | 62 | const blocks = component.find(Block); 63 | blocks.forEach(block => { 64 | expect(hasCustomColor(block)).toBeTruthy(); 65 | }); 66 | }); 67 | 68 | it('has assigned className', () => { 69 | const component = mount(); 70 | expect(component.hasClass('testClass')).toBeTruthy(); 71 | }); 72 | 73 | it('has assigned styles', () => { 74 | const style = { width: '600px' }; 75 | const component = mount(); 76 | 77 | expect(component.prop('style')).toBe(style); 78 | }); 79 | 80 | it('has assigned id', () => { 81 | const component = mount(); 82 | expect(component.find('#testId').hostNodes()).toHaveLength(1); 83 | }); 84 | 85 | it('positions label correctly', () => { 86 | const component = mount(); 87 | expect(component.find(Label).prop('position')).toBe('bottom'); 88 | }); 89 | 90 | it('handles custom label style', () => { 91 | const component = mount( 92 | 93 | ); 94 | const label = component.find(Label); 95 | 96 | expect(label).toHaveLength(1); 97 | expect(label.prop('style').color).toBe('blue'); 98 | }); 99 | 100 | it('handles gradient color scheme', () => { 101 | const gradient = { gradient: true, ranges: { green: [0, 5], yellow: [5, 7], red: [7, 10] } }; 102 | const component = mount(); 103 | 104 | const block = component.find(Block).first(); 105 | 106 | // we don't actually call `.css()` but this is an easy way to visualize the props being passed 107 | expect(block.prop('gradient').css()).toEqual( 108 | 'linear-gradient(to right, rgb(0, 128, 0) 0%, rgb(255, 255, 0) 50%, rgb(255, 0, 0) 70%, rgb(255, 0, 0) 100%)' 109 | ); 110 | }); 111 | }); 112 | -------------------------------------------------------------------------------- /src/components/__tests__/Indicator.test.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | import React from 'react'; 3 | import Enzyme from 'enzyme'; 4 | import Adapter from 'enzyme-adapter-react-16'; 5 | Enzyme.configure({ adapter: new Adapter() }); 6 | 7 | import { mount } from 'enzyme'; 8 | 9 | import Indicator from '../Indicator.react'; 10 | import IndicatorLight from '../../styled/shared/Indicator.styled'; 11 | import Label from '../../styled/shared/Label.styled'; 12 | import DarkThemeProvider from '../DarkThemeProvider.react'; 13 | 14 | describe.only('Thermometer', () => { 15 | it('renders', () => { 16 | const component = mount(); 17 | expect(component).toBeTruthy(); 18 | }); 19 | 20 | it('renders dark theme', () => { 21 | const component = mount( 22 | 23 | 24 | 25 | ); 26 | expect(component).toBeTruthy(); 27 | }); 28 | 29 | it('renders circular indicator if only height is set', () => { 30 | const component = mount(); 31 | expect(component.find(IndicatorLight).prop('rectangular')).toBeFalsy(); 32 | }); 33 | 34 | it('renders circular indicator if only width is set', () => { 35 | const component = mount(); 36 | expect(component.find(IndicatorLight).prop('rectangular')).toBeFalsy(); 37 | }); 38 | 39 | it('renders rectangular indicator if height and width are both set', () => { 40 | const component = mount(); 41 | expect(component.find(IndicatorLight).prop('rectangular')).toBeTruthy(); 42 | }); 43 | 44 | it('lights up when on', () => { 45 | const component = mount(); 46 | expect(component.find(IndicatorLight).prop('on')).toBeTruthy(); 47 | }); 48 | 49 | it('does not light up when off', () => { 50 | const component = mount(); 51 | expect(component.find(IndicatorLight).prop('on')).toBeFalsy(); 52 | }); 53 | 54 | it('has assigned className', () => { 55 | const component = mount(); 56 | expect(component.hasClass('testClass')).toBeTruthy(); 57 | }); 58 | 59 | it('has assigned styles', () => { 60 | const style = { width: '600px' }; 61 | const component = mount(); 62 | 63 | expect(component.prop('style')).toBe(style); 64 | }); 65 | 66 | it('has assigned id', () => { 67 | const component = mount(); 68 | expect(component.find('#testId').hostNodes()).toHaveLength(1); 69 | }); 70 | 71 | it('positions label correctly', () => { 72 | const component = mount(); 73 | expect(component.find(Label).prop('position')).toBe('bottom'); 74 | }); 75 | 76 | it('handles custom label style', () => { 77 | const component = mount( 78 | 79 | ); 80 | const label = component.find(Label); 81 | 82 | expect(label).toHaveLength(1); 83 | expect(label.prop('style').color).toBe('blue'); 84 | }); 85 | }); 86 | -------------------------------------------------------------------------------- /src/components/__tests__/NumericInput.test.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | import React from 'react'; 3 | import Enzyme from 'enzyme'; 4 | import Adapter from 'enzyme-adapter-react-16'; 5 | Enzyme.configure({ adapter: new Adapter() }); 6 | 7 | import { mount, shallow } from 'enzyme'; 8 | import sinon from 'sinon'; 9 | 10 | import NumericInput from '../NumericInput.react'; 11 | import Label from '../../styled/shared/Label.styled'; 12 | import DarkThemeProvider from '../DarkThemeProvider.react'; 13 | 14 | describe.only('Numeric Input', () => { 15 | it('renders', () => { 16 | const component = mount(); 17 | expect(component).toBeTruthy(); 18 | }); 19 | 20 | it('renders dark theme', () => { 21 | const component = mount( 22 | 23 | 24 | 25 | ); 26 | expect(component).toBeTruthy(); 27 | }); 28 | 29 | it('updates value when props change', () => { 30 | const component = mount(); 31 | 32 | component.setProps({ value: 3 }); 33 | expect(component.prop('value')).toBe(3); 34 | }); 35 | 36 | it('does not update value on prop change without value set', () => { 37 | const component = mount(shallow().get(0)); 38 | 39 | component.setProps({}); 40 | expect(component.state('value')).toBe(2); 41 | }); 42 | 43 | it('updates value when setValue is called', () => { 44 | const component = mount(shallow().get(0)); 45 | 46 | component.instance().setValue(3); 47 | expect(component.state('value')).toBe(3); 48 | }); 49 | 50 | it('does not update value when setValue is called with null', () => { 51 | const component = mount(shallow().get(0)); 52 | 53 | component.instance().setValue(null); 54 | expect(component.state('value')).toBe(2); 55 | }); 56 | 57 | it('setProps is called when setValue is called', () => { 58 | const setProps = sinon.spy(); 59 | const component = mount(shallow().get(0)); 60 | 61 | component.instance().setValue(3); 62 | expect(setProps.calledOnce).toBeTruthy(); 63 | expect(setProps.getCall(0).args[0].value).toBe(3); 64 | }); 65 | 66 | it('setProps does not throw when not bound', () => { 67 | const component = mount(shallow().get(0)); 68 | 69 | component.instance().setValue(3); 70 | }); 71 | 72 | it('has assigned className', () => { 73 | const component = mount(); 74 | expect(component.hasClass('testClass')).toBeTruthy(); 75 | }); 76 | 77 | it('has assigned styles', () => { 78 | const style = { width: '600px' }; 79 | const component = mount(); 80 | 81 | expect(component.prop('style')).toBe(style); 82 | }); 83 | 84 | it('has assigned id', () => { 85 | const component = mount(); 86 | expect(component.find('#testId').hostNodes()).toHaveLength(1); 87 | }); 88 | 89 | it('positions label correctly', () => { 90 | const component = mount(); 91 | expect(component.find(Label).prop('position')).toBe('bottom'); 92 | }); 93 | 94 | it('handles custom label style', () => { 95 | const component = mount( 96 | 97 | ); 98 | const label = component.find(Label); 99 | 100 | expect(label).toHaveLength(1); 101 | expect(label.prop('style').color).toBe('blue'); 102 | }); 103 | }); 104 | -------------------------------------------------------------------------------- /src/components/__tests__/PowerButton.test.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | import React from 'react'; 3 | import Enzyme from 'enzyme'; 4 | import Adapter from 'enzyme-adapter-react-16'; 5 | Enzyme.configure({ adapter: new Adapter() }); 6 | 7 | import { mount, shallow } from 'enzyme'; 8 | import sinon from 'sinon'; 9 | 10 | import PowerButton from '../PowerButton.react'; 11 | import Indicator from '../../styled/shared/Indicator.styled'; 12 | import LabelContainer from '../../styled/shared/LabelContainer.styled'; 13 | import Label from '../../styled/shared/Label.styled'; 14 | import DarkThemeProvider from '../DarkThemeProvider.react'; 15 | 16 | describe('Power Button', () => { 17 | it('renders', () => { 18 | const component = mount(); 19 | expect(component).toBeTruthy(); 20 | }); 21 | 22 | it('renders dark theme', () => { 23 | const component = mount( 24 | 25 | 26 | 27 | ); 28 | expect(component).toBeTruthy(); 29 | }); 30 | 31 | it('updates on when props change', () => { 32 | const component = mount(); 33 | expect(component.prop('on')).toBeFalsy(); 34 | 35 | component.setProps({ on: true }); 36 | expect(component.prop('on')).toBeTruthy(); 37 | }); 38 | 39 | it('does not update on value when props change without on set', () => { 40 | const component = mount(shallow().get(0)); 41 | 42 | component.setProps({}); 43 | expect(component.state('on')).toBeTruthy(); 44 | }); 45 | 46 | it('calls setProps on click', () => { 47 | const setProps = sinon.spy(); 48 | const component = mount(); 49 | 50 | component.find('button').simulate('click'); 51 | 52 | expect(setProps.calledOnce).toBeTruthy(); 53 | expect(setProps.getCall(0).args[0].on).toBeTruthy(); 54 | }); 55 | 56 | it('handles absent setProps callbacks', () => { 57 | const component = mount(); 58 | 59 | component.find('button').simulate('click'); 60 | }); 61 | 62 | it('has assigned className', () => { 63 | const component = mount(); 64 | expect(component.hasClass('testClass')).toBeTruthy(); 65 | }); 66 | 67 | it('has assigned styles', () => { 68 | const style = { width: '600px' }; 69 | const component = mount(); 70 | 71 | expect(component.prop('style')).toBe(style); 72 | }); 73 | 74 | it('has assigned id', () => { 75 | const component = mount(); 76 | expect(component.find('#testId').hostNodes()).toHaveLength(1); 77 | }); 78 | 79 | it('positions label correctly', () => { 80 | const component = mount(); 81 | expect(component.find(LabelContainer).prop('labelPosition')).toBe('bottom'); 82 | }); 83 | 84 | it('handles custom label style', () => { 85 | const component = mount( 86 | 87 | ); 88 | const label = component.find(Label); 89 | 90 | expect(label).toHaveLength(1); 91 | expect(label.prop('style').color).toBe('blue'); 92 | }); 93 | }); 94 | -------------------------------------------------------------------------------- /src/components/__tests__/StopButton.test.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | import React from 'react'; 3 | import Enzyme from 'enzyme'; 4 | import Adapter from 'enzyme-adapter-react-16'; 5 | Enzyme.configure({ adapter: new Adapter() }); 6 | 7 | import { mount } from 'enzyme'; 8 | import sinon from 'sinon'; 9 | 10 | import StopButton from '../StopButton.react'; 11 | import LabelContainer from '../../styled/shared/LabelContainer.styled'; 12 | import Label from '../../styled/shared/Label.styled'; 13 | import DarkThemeProvider from '../DarkThemeProvider.react'; 14 | 15 | describe('Stop Button', () => { 16 | it('renders', () => { 17 | const component = mount(); 18 | expect(component).toBeTruthy(); 19 | }); 20 | 21 | it('renders dark theme', () => { 22 | const component = mount( 23 | 24 | {' '} 25 | 26 | ); 27 | expect(component).toBeTruthy(); 28 | }); 29 | 30 | it('sets custom button text', () => { 31 | const component = mount(custom_text); 32 | expect(component.render().text()).toBe('custom_text'); 33 | }); 34 | 35 | it('calls setProps with n_clicks', () => { 36 | const setProps = sinon.spy(); 37 | const component = mount(); 38 | 39 | component.find('button').simulate('click'); 40 | 41 | expect(setProps.calledOnce).toBeTruthy(); 42 | expect(setProps.getCall(0).args[0].n_clicks).toBe(1); 43 | }); 44 | 45 | it('handles unbound setProps prop', () => { 46 | const component = mount(); 47 | 48 | component.find('button').simulate('click'); 49 | }); 50 | 51 | it('has assigned id', () => { 52 | const component = mount(); 53 | expect(component.find('#testId').hostNodes()).toHaveLength(1); 54 | }); 55 | 56 | it('has assigned className', () => { 57 | const component = mount(); 58 | expect(component.hasClass('testClass')).toBeTruthy(); 59 | }); 60 | 61 | it('has assigned styles', () => { 62 | const style = { width: '600px' }; 63 | const component = mount(); 64 | 65 | expect(component.prop('style')).toBe(style); 66 | }); 67 | 68 | it('positions label correctly', () => { 69 | const component = mount(); 70 | expect(component.find(LabelContainer).prop('labelPosition')).toBe('bottom'); 71 | }); 72 | 73 | it('handles custom label style', () => { 74 | const component = mount( 75 | 76 | ); 77 | const label = component.find(Label); 78 | 79 | expect(label).toHaveLength(1); 80 | expect(label.prop('style').color).toBe('blue'); 81 | }); 82 | }); 83 | -------------------------------------------------------------------------------- /src/fragments/ColorPicker.react.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import { ChromePicker } from 'react-color'; 3 | import { withTheme } from 'styled-components'; 4 | import Color from 'color'; 5 | 6 | import { colors } from '../styled/constants'; 7 | import { Container } from '../styled/ColorPicker.styled'; 8 | import LabelContainer from '../styled/shared/LabelContainer.styled'; 9 | 10 | import { defaultProps, propTypes } from '../components/ColorPicker.react'; 11 | 12 | import { getClassName, getFilteredProps } from '../helpers/classNameGenerator'; 13 | 14 | const DEFAULT_COLOR = colors.PRIMARY; 15 | 16 | const parseValue = value => { 17 | value = value || {}; 18 | 19 | if (value.rgb) { 20 | const rgba = Object.values(value.rgb); 21 | return `rgba(${rgba[0]}, ${rgba[1]}, ${rgba[2]}, ${rgba[3]})`; 22 | } 23 | 24 | if (value.hex) 25 | return Color(value.hex) 26 | .rgb() 27 | .string(); 28 | 29 | return DEFAULT_COLOR; 30 | }; 31 | 32 | /** 33 | * A color picker. 34 | */ 35 | class ColorPicker extends Component { 36 | constructor(props) { 37 | super(props); 38 | 39 | this.state = { 40 | value: props.value 41 | }; 42 | 43 | this.calcHandleGlow = this.calcHandleGlow.bind(this); 44 | this.setValue = this.setValue.bind(this); 45 | } 46 | 47 | UNSAFE_componentWillReceiveProps(newProps) { 48 | if (newProps.value !== this.state.value) this.setState({ value: newProps.value }); 49 | } 50 | 51 | calcHandleGlow() { 52 | return Color(parseValue(this.state.value)) 53 | .fade(0.5) 54 | .string(); 55 | } 56 | 57 | setValue(value) { 58 | if (value != null) { 59 | const { hex, rgb } = value; 60 | const newValue = { hex, rgb }; 61 | 62 | this.setState({ value: newValue }); 63 | if (this.props.setProps) this.props.setProps({ value: newValue }); 64 | } 65 | } 66 | 67 | render() { 68 | const { id, className, style, theme } = this.props; 69 | 70 | const elementName = getClassName('colorpicker', theme); 71 | 72 | const filteredProps = getFilteredProps(this.props); 73 | 74 | return ( 75 |
76 | 77 | 82 | 87 | 88 | 89 |
90 | ); 91 | } 92 | } 93 | 94 | ColorPicker.defaultProps = defaultProps; 95 | ColorPicker.propTypes = propTypes; 96 | 97 | export default withTheme(ColorPicker); 98 | -------------------------------------------------------------------------------- /src/helpers/NumericInput.js: -------------------------------------------------------------------------------- 1 | import { default as Input } from 'react-numeric-input'; 2 | 3 | Input.prototype.UNSAFE_componentWillMount = Input.prototype.componentWillMount; 4 | Input.prototype.UNSAFE_componentWillReceiveProps = Input.prototype.componentWillReceiveProps; 5 | Input.prototype.UNSAFE_componentWillUpdate = Input.prototype.componentWillUpdate; 6 | 7 | delete Input.prototype.componentWillMount; 8 | delete Input.prototype.componentWillReceiveProps; 9 | delete Input.prototype.componentWillUpdate; 10 | 11 | export default Input; 12 | -------------------------------------------------------------------------------- /src/helpers/PowerButtonSvg.react.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import { light } from '../styled/constants'; 4 | 5 | const PowerButtonSvg = ({ color, theme, on, size }) => ( 6 | 7 | 13 | 14 | ); 15 | 16 | PowerButtonSvg.defaultProps = { 17 | theme: light 18 | }; 19 | 20 | export default PowerButtonSvg; 21 | -------------------------------------------------------------------------------- /src/helpers/classNameGenerator.js: -------------------------------------------------------------------------------- 1 | import { omit } from 'ramda'; 2 | 3 | export const getClassName = (componentName, theme) => { 4 | return 'daq-' + componentName + (theme && theme.dark ? '--dark' : '--light'); 5 | }; 6 | 7 | export const getFilteredProps = props => omit(['className', 'id', 'setProps', 'style'], props); 8 | -------------------------------------------------------------------------------- /src/helpers/logarithm.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import styled from 'styled-components'; 3 | 4 | import { roundToDecimal } from './util'; 5 | 6 | function compute(value, base = 10) { 7 | if (base === 'e') base = Math.exp(1); 8 | 9 | return Math.log(value) / Math.log(base); 10 | } 11 | 12 | function generateLogFormatter({ base = 10, isSVG = false }) { 13 | return value => 14 | isSVG ? ( 15 | 16 | {base} 17 | {value} 18 | 19 | ) : ( 20 | 21 | {base} 22 | {value} 23 | 24 | ); 25 | } 26 | 27 | function genLogMarks({ min, max, step = 1, base = 10, marks }, isSVG) { 28 | // if no marks given, compute default marks 29 | if (!marks) { 30 | let curr = min; 31 | marks = {}; 32 | 33 | while (curr <= max) { 34 | marks[curr] = true; 35 | curr += step; 36 | } 37 | } 38 | 39 | Object.keys(marks).forEach(key => { 40 | if (typeof marks[key] !== 'boolean') { 41 | // custom mark label, do not format 42 | return; 43 | } 44 | 45 | marks[key] = isSVG ? ( 46 | 47 | {base} 48 | {key} 49 | 50 | ) : ( 51 | 52 | {base} 53 | {key} 54 | 55 | ); 56 | }); 57 | 58 | return marks; 59 | } 60 | 61 | function formatValue(value, base) { 62 | return ( 63 | 64 | ~{base} 65 | {roundToDecimal(value, 2)} 66 | 67 | ); 68 | } 69 | 70 | const Value = styled.div` 71 | font-size: 0.9em; 72 | margin-left: -10px; 73 | 74 | & sup { 75 | font-size: 0.6em; 76 | } 77 | `; 78 | 79 | export default { 80 | compute, 81 | generateLogFormatter, 82 | formatValue, 83 | genLogMarks 84 | }; 85 | -------------------------------------------------------------------------------- /src/helpers/scale.js: -------------------------------------------------------------------------------- 1 | import { decimalify } from './util'; 2 | 3 | // magic numbers 4 | const DEFAULT_NUM_INTERVALS = 10; 5 | const DEFAULT_LABEL_INTERVAL = 2; 6 | 7 | export default function generateScale(input) { 8 | const config = processInput(input); 9 | 10 | const scale = { 11 | ...config.custom 12 | }; 13 | 14 | if (config.onlyRenderCustom) { 15 | return scale; 16 | } 17 | 18 | scale[config.min] = config.formatter(config.min); 19 | scale[config.max] = config.formatter(config.max); 20 | 21 | let curr = config.start; 22 | let markCount = 0; 23 | while (curr <= config.max) { 24 | const needsLabel = markCount % config.labelInterval === 0; 25 | const currValue = Number(decimalify(curr, config.interval)); 26 | const alreadyMarked = typeof scale[currValue] !== 'undefined'; 27 | 28 | curr += config.interval; 29 | markCount++; 30 | 31 | if (alreadyMarked) continue; 32 | 33 | const label = needsLabel ? config.formatter(currValue) : null; 34 | scale[currValue] = label; 35 | } 36 | 37 | return scale; 38 | } 39 | 40 | // private 41 | function processInput({ min, max, scale = {}, formatter }) { 42 | const config = {}; 43 | 44 | const START_FLAG = scale.start != null; 45 | const INTERVAL_FLAG = scale.interval != null; 46 | const LABEL_INTERVAL_FLAG = scale.labelInterval != null; 47 | 48 | config.min = min; 49 | config.max = max; 50 | config.start = START_FLAG ? scale.start : min; 51 | config.interval = INTERVAL_FLAG ? scale.interval : computeInterval(config.start, max); 52 | config.labelInterval = LABEL_INTERVAL_FLAG ? scale.labelInterval : DEFAULT_LABEL_INTERVAL; 53 | config.custom = scale.custom || {}; 54 | config.formatter = formatter || identityFunc; 55 | 56 | const noConfigPassed = !START_FLAG && !INTERVAL_FLAG && !LABEL_INTERVAL_FLAG; 57 | const customTicks = Object.keys(config.custom).length; 58 | config.onlyRenderCustom = customTicks && noConfigPassed; 59 | config.start = config.start != min ? min : config.start; 60 | 61 | return config; 62 | } 63 | 64 | function identityFunc(x) { 65 | return x; 66 | } 67 | 68 | function computeInterval(min, max) { 69 | const ROUND_TO_WHOLE = Math.ceil; 70 | const ROUND_TO_FRACTION = x => Number(x.toFixed(2)); 71 | 72 | const range = Math.abs(max - min) * 1.0; 73 | const intervalEstimate = range / DEFAULT_NUM_INTERVALS; 74 | const interval = 75 | intervalEstimate > 1 ? ROUND_TO_WHOLE(intervalEstimate) : ROUND_TO_FRACTION(intervalEstimate); 76 | 77 | return interval; 78 | } 79 | -------------------------------------------------------------------------------- /src/helpers/util.js: -------------------------------------------------------------------------------- 1 | export const longestString = arr => 2 | arr.sort(function(a, b) { 3 | return b.length - a.length; 4 | })[0]; 5 | 6 | export const decimalify = (num = 0, step) => { 7 | if (isNaN(num)) { 8 | return num; 9 | } 10 | 11 | // eslint-disable-next-line 12 | const [characteristic, mantissa] = step.toString().split('.'); 13 | 14 | const numDecimalPoints = mantissa ? mantissa.length : 0; 15 | 16 | return num.toFixed(numDecimalPoints); 17 | }; 18 | 19 | export const sanitizeRangeValue = ({ min, max, value }) => { 20 | if (value == null) return min; 21 | 22 | if (value < min) { 23 | return min; 24 | } else if (value > max) { 25 | return max; 26 | } else { 27 | return value; 28 | } 29 | }; 30 | 31 | export const computeProgress = ({ min, max, value, progressionTarget = 100 }) => { 32 | value = Number(value); 33 | const adjustedValue = Math.abs(value - min) * 1.0; 34 | const range = Math.abs(max - min); 35 | 36 | return (adjustedValue / range) * progressionTarget; 37 | }; 38 | 39 | export const roundToDecimal = (value, decimals) => 40 | Number(Math.round(value + 'e' + decimals) + 'e-' + decimals); 41 | 42 | export const getRandomInt = (min = 0, max = 9999) => 43 | Math.floor(Math.random() * (max - min + 1)) + min; 44 | 45 | export default { 46 | decimalify, 47 | sanitizeRangeValue, 48 | computeProgress, 49 | longestString, 50 | roundToDecimal, 51 | getRandomInt 52 | }; 53 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable import/prefer-default-export */ 2 | export { default as BooleanSwitch } from './components/BooleanSwitch.react'; 3 | export { default as ColorPicker } from './components/ColorPicker.react'; 4 | export { default as Gauge } from './components/Gauge.react'; 5 | export { default as GraduatedBar } from './components/GraduatedBar.react'; 6 | export { default as Indicator } from './components/Indicator.react'; 7 | export { default as Knob } from './components/Knob.react'; 8 | export { default as LEDDisplay } from './components/LEDDisplay.react'; 9 | export { default as NumericInput } from './components/NumericInput.react'; 10 | export { default as PowerButton } from './components/PowerButton.react'; 11 | export { default as PrecisionInput } from './components/PrecisionInput.react'; 12 | export { default as StopButton } from './components/StopButton.react'; 13 | export { default as Slider } from './components/Slider.react'; 14 | export { default as Tank } from './components/Tank.react'; 15 | export { default as Thermometer } from './components/Thermometer.react'; 16 | export { default as ToggleSwitch } from './components/ToggleSwitch.react'; 17 | export { default as DarkThemeProvider } from './components/DarkThemeProvider.react'; 18 | export { default as Joystick } from './components/Joystick.react'; 19 | -------------------------------------------------------------------------------- /src/styled/CurrentValue.styled.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import styled, { css } from 'styled-components'; 3 | 4 | import { light } from './constants'; 5 | 6 | const ValueContainer = styled.div` 7 | position: relative; 8 | display: flex; 9 | flex-direction: column; 10 | justify-content: space-around; 11 | align-items: center; 12 | 13 | top: 50%; 14 | transform: translateY(-50%); 15 | text-align: center; 16 | font-size: 32px; 17 | ${props => 18 | props.css 19 | ? css` 20 | ${props.css}; 21 | ` 22 | : ''}; 23 | `; 24 | 25 | export const Value = styled.div` 26 | font-size: 1em; 27 | color: ${({ theme, color }) => color || (theme.dark ? '#000' : color || theme.primary)}; 28 | ${({ theme }) => 29 | theme.dark 30 | ? css` 31 | text-shadow: 0px 0px 1px rgba(0, 0, 0, 0.4); 32 | ` 33 | : ''}; 34 | ${({ fontSize }) => { 35 | return fontSize 36 | ? css` 37 | font-size: ${fontSize}px; 38 | ` 39 | : ''; 40 | }} 41 | `; 42 | 43 | Value.defaultProps = { 44 | theme: light 45 | }; 46 | 47 | export const ValueLabel = styled.label` 48 | margin-top: -4px; 49 | text-transform: uppercase; 50 | font-size: 8px; 51 | color: #535d63; 52 | `; 53 | 54 | export default props => ( 55 | 56 | 57 | {props.children} 58 | 59 | {props.units ? {props.units} : null} 60 | 61 | ); 62 | -------------------------------------------------------------------------------- /src/styled/Gauge.styled.js: -------------------------------------------------------------------------------- 1 | import styled, { css } from 'styled-components'; 2 | import { light } from '../styled/constants'; 3 | 4 | const Container = styled.div` 5 | & svg { 6 | text-align: center; 7 | } 8 | 9 | & circle { 10 | user-select: none; 11 | } 12 | 13 | & .scale { 14 | font-size: 12px; 15 | 16 | fill: ${({ theme, color }) => color || (theme.dark ? '#000' : '#5b6268')}; 17 | user-select: none; 18 | } 19 | 20 | & .tick { 21 | stroke: ${props => props.theme.detail}; 22 | stroke-width: 2; 23 | } 24 | 25 | & .tick.small { 26 | stroke: #2b2f32; 27 | } 28 | 29 | & .needle { 30 | stroke: ${({ theme }) => (theme.dark ? '#000' : '#5b6268')}; 31 | stroke-width: 3; 32 | } 33 | 34 | ${({ theme }) => !theme.dark && lightTheme}; 35 | `; 36 | 37 | const lightTheme = css` 38 | & .needle-knob { 39 | stroke: ${({ theme }) => theme.secondary}; 40 | stroke-width: 2; 41 | } 42 | 43 | & .track { 44 | stroke: ${props => props.theme.secondary}; 45 | } 46 | 47 | & .track.progress { 48 | stroke: ${({ color, theme }) => color || theme.primary}; 49 | } 50 | `; 51 | 52 | Container.defaultProps = { 53 | theme: light 54 | }; 55 | 56 | export default Container; 57 | -------------------------------------------------------------------------------- /src/styled/GraduatedBar.styled.js: -------------------------------------------------------------------------------- 1 | import styled, { css } from 'styled-components'; 2 | import { light } from './constants'; 3 | 4 | export const Container = styled.div` 5 | position: relative; 6 | display: flex; 7 | align-items: center; 8 | justify-content: flex-start; 9 | 10 | ${({ vertical }) => (vertical ? verticalContainer : horizontalContainer)}; 11 | ${({ theme }) => (theme.dark ? darkContainer : lightContainer)}; 12 | `; 13 | 14 | Container.defaultProps = { 15 | theme: light 16 | }; 17 | 18 | const verticalContainer = css` 19 | flex-direction: column-reverse; 20 | width: 30px; 21 | height: ${({ size }) => `${size}px`}; 22 | `; 23 | 24 | const horizontalContainer = css` 25 | flex-direction: row; 26 | width: ${({ size }) => `${size}px`}; 27 | height: 30px; 28 | `; 29 | 30 | const darkContainer = css` 31 | text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.8); 32 | padding: 3px; 33 | color: #fff; 34 | border: none; 35 | border-radius: 0px; 36 | background-color: #22272a; 37 | background-image: linear-gradient(145deg, rgba(255, 255, 255, 0.05) 0%, rgba(0, 0, 0, 0.5) 100%); 38 | box-shadow: inset 0 0 8px -1px rgba(0, 0, 0, 0.7), inset 0 0 4px 0 rgba(0, 0, 0, 0.8), 39 | -1px -1px 0px 0px rgba(0, 0, 0, 0.8), 1px 1px 0px 0px rgba(255, 255, 255, 0.1); 40 | `; 41 | 42 | const lightContainer = css` 43 | background-color: ${props => props.theme.secondary}; 44 | `; 45 | 46 | export const Block = styled.div` 47 | display: block; 48 | box-sizing: border-box; 49 | 50 | ${({ gradient, progress, color, theme, max, min, step, size, vertical }) => { 51 | if (gradient) { 52 | const TOTAL_STEPS = (max - min) / step; 53 | const STEP_SIZE = size / TOTAL_STEPS; 54 | const STEP_SIZE_PERCENT = STEP_SIZE / size; 55 | 56 | const start = gradient.rgbAt(progress).toString(); 57 | const end = gradient.rgbAt(progress + STEP_SIZE_PERCENT).toString(); 58 | 59 | return css` 60 | background-image: linear-gradient(${vertical ? 'to top' : 'to right'}, ${start}, ${end}); 61 | `; 62 | } 63 | 64 | return css` 65 | background-color: ${color || theme.primary}; 66 | `; 67 | }} 68 | 69 | ${props => { 70 | const TOTAL_STEPS = (props.max - props.min) / props.step; 71 | const STEP_SIZE = props.size / TOTAL_STEPS; 72 | const MARGIN = STEP_SIZE >= 10 ? STEP_SIZE * 0.05 : 0.5; 73 | const BOX_SIZE = STEP_SIZE - 2 * MARGIN; 74 | return css` 75 | height: ${props.vertical ? `${BOX_SIZE}px` : '100%'}; 76 | width: ${props.vertical ? '100%' : `${BOX_SIZE}px`}; 77 | margin: ${props.vertical ? `${MARGIN}px 0` : `0 ${MARGIN}px`}; 78 | `; 79 | }} 80 | 81 | ${({ theme }) => theme.dark && darkBlock}; 82 | `; 83 | 84 | Block.defaultProps = { 85 | theme: light 86 | }; 87 | 88 | const darkBlock = css` 89 | ${({ color, theme, gradient }) => { 90 | if (gradient) return; 91 | 92 | return css` 93 | background-color: ${color || theme.primary}; 94 | background-image: linear-gradient( 95 | 145deg, 96 | rgba(255, 255, 255, 0.5) 0%, 97 | rgba(0, 0, 0, 0.4) 100% 98 | ); 99 | background-blend-mode: overlay; 100 | `; 101 | }} box-shadow: ${({ color, theme }) => 102 | `2px 2px 6px 1px rgba(0, 0, 0, 0.45), inset 1px 1px 2px 0 rgba(255, 255, 255, 0.3), 103 | 1px 1px 1px 0px rgba(0, 0, 0, 0.6), 0 0 3px 0px ${color || theme.primary}`}; 104 | `; 105 | 106 | export const Value = styled.div` 107 | position: absolute; 108 | right: 4%; 109 | top: 50%; 110 | transform: translateY(-50%); 111 | 112 | ${({ vertical }) => 113 | vertical 114 | ? css` 115 | font-size: 11px; 116 | right: auto; 117 | ` 118 | : ''}; 119 | `; 120 | -------------------------------------------------------------------------------- /src/styled/Knob.styled.js: -------------------------------------------------------------------------------- 1 | import styled, { css } from 'styled-components'; 2 | import { light } from './constants'; 3 | 4 | const Container = styled.div` 5 | display: flex; 6 | align-items: center; 7 | flex-direction: column; 8 | & svg { 9 | text-align: center; 10 | } 11 | 12 | & circle { 13 | user-select: none; 14 | } 15 | 16 | & .scale { 17 | font-size: 12px; 18 | user-select: none; 19 | fill: ${({ colorValue }) => colorValue || 'black'} !important; 20 | } 21 | 22 | & .tick { 23 | stroke: ${props => props.theme.detail}; 24 | stroke-width: 2; 25 | } 26 | 27 | & .knob { 28 | cursor: pointer; 29 | } 30 | 31 | & .disabled { 32 | opacity: ${({ theme }) => (theme.dark ? 1 : 0.65)}; 33 | cursor: not-allowed; 34 | } 35 | 36 | & .track.progress { 37 | stroke: ${({ color, theme }) => color || theme.primary}; 38 | } 39 | 40 | ${({ theme }) => (theme.dark ? darkTheme : lightTheme)}; 41 | `; 42 | 43 | const lightTheme = css` 44 | & .scale { 45 | fill: #5b6268; 46 | } 47 | 48 | & .track { 49 | stroke: #e6e6e6; 50 | } 51 | 52 | & .knob .base, 53 | .knob .indent { 54 | stroke: #e6e6e6; 55 | stroke-width: 2; 56 | } 57 | `; 58 | 59 | const darkTheme = css` 60 | & .scale { 61 | fill: #fff; 62 | } 63 | `; 64 | 65 | Container.defaultProps = { 66 | theme: light 67 | }; 68 | 69 | export default Container; 70 | -------------------------------------------------------------------------------- /src/styled/LEDDisplay.styled.js: -------------------------------------------------------------------------------- 1 | import styled, { css } from 'styled-components'; 2 | 3 | import { light } from './constants'; 4 | 5 | export const LEDContainer = styled.div` 6 | display: inline-flex; 7 | flex-direction: row; 8 | ${({ theme }) => (theme.dark ? darkLEDContainer : lightLEDContainer)}; 9 | ${({ backgroundColor }) => 10 | css` 11 | background-color: ${backgroundColor}; 12 | `} 13 | `; 14 | 15 | const darkLEDContainer = css` 16 | padding: 12px 8px 4px 16px; 17 | background-color: #22272a; 18 | background-image: linear-gradient(145deg, rgba(255, 255, 255, 0.05) 0%, rgba(0, 0, 0, 0.5) 100%); 19 | box-shadow: inset 0 0 8px -1px rgba(0, 0, 0, 0.7), inset 0 0 4px 0 rgba(0, 0, 0, 0.8), 20 | -1px -1px 0px 0px rgba(0, 0, 0, 0.8), 1px 1px 0px 0px rgba(255, 255, 255, 0.1); 21 | `; 22 | 23 | const lightLEDContainer = css` 24 | border-radius: 3px; 25 | padding: 12px 8px 12px 14px; 26 | border: 1px solid ${({ theme }) => theme.detail}; 27 | background: ${({ backgroundColor }) => backgroundColor}; 28 | `; 29 | 30 | LEDContainer.defaultProps = { 31 | theme: light 32 | }; 33 | 34 | export const DarkDigitContainer = styled.div` 35 | & .darkLED-fill { 36 | fill: ${({ color }) => color}; 37 | } 38 | `; 39 | 40 | export default LEDContainer; 41 | -------------------------------------------------------------------------------- /src/styled/PowerButton.styled.js: -------------------------------------------------------------------------------- 1 | import styled, { css } from 'styled-components'; 2 | import { light } from '../styled/constants'; 3 | 4 | export const Container = styled('div')` 5 | display: flex; 6 | flex-direction: column; 7 | justify-content: space-between; 8 | align-items: center; 9 | 10 | & svg { 11 | margin: 0 auto; 12 | } 13 | `; 14 | 15 | export const Button = styled.button` 16 | cursor: pointer; 17 | outline: none; 18 | display: flex; 19 | justify-content: center; 20 | align-items: center; 21 | 22 | &:disabled { 23 | opacity: ${({ theme }) => (theme.dark ? 1 : 0.65)}; 24 | cursor: not-allowed; 25 | } 26 | 27 | ${({ theme }) => (theme.dark ? darkTheme : lightTheme)}; 28 | `; 29 | 30 | const lightTheme = css` 31 | border-radius: 50%; 32 | box-sizing: border-box; 33 | background: #fff; 34 | border: 1px solid ${props => props.theme.secondary}; 35 | ${({ size }) => 36 | css` 37 | width: ${size}px; 38 | height: ${size}px; 39 | `} margin-bottom: ${({ size }) => `${size * 0.0625}px`}; 40 | padding: 0; 41 | 42 | &:focus, 43 | &:hover { 44 | border-color: ${props => props.theme.secondary}; 45 | } 46 | `; 47 | 48 | const darkTheme = css` 49 | ${({ size }) => 50 | css` 51 | width: ${size}px; 52 | height: ${size}px; 53 | `} border-radius: 100%; 54 | padding: 0; 55 | margin-bottom: 8px; 56 | 57 | &::before, 58 | &::after { 59 | left: 4%; 60 | border-radius: 100%; 61 | transition: all 0.1s ease-in; 62 | } 63 | 64 | &::before { 65 | top: 8%; 66 | width: 86%; 67 | height: 86%; 68 | } 69 | 70 | &::after { 71 | top: 4%; 72 | width: 92%; 73 | height: 92%; 74 | 75 | ${({ on, color, theme }) => 76 | on 77 | ? css` 78 | box-shadow: 0 0 8px 2px ${color || theme.primary}; 79 | ` 80 | : ''}; 81 | } 82 | 83 | &:hover::before { 84 | background-color: rgba(0, 0, 0, 0.8); 85 | } 86 | 87 | &:hover::after { 88 | box-shadow: 0 0 3px 0 rgba(0, 0, 0, 0.66); 89 | } 90 | 91 | &:focus::after, 92 | &:active::after { 93 | box-shadow: ${({ on, color, theme }) => 94 | on ? `0 0 8px 2px ${color || theme.primary}` : '0 0 3px 0 rgba(0,0,0,0.66)'}; 95 | } 96 | `; 97 | 98 | Button.defaultProps = { 99 | theme: light 100 | }; 101 | -------------------------------------------------------------------------------- /src/styled/PrecisionInput.styled.js: -------------------------------------------------------------------------------- 1 | import styled, { css } from 'styled-components'; 2 | 3 | export const Container = styled.div` 4 | margin: 0 auto; 5 | display: flex; 6 | justify-content: flex-end; 7 | width: ${({ size }) => `${size}px` || 'auto'}; 8 | cursor: text; 9 | 10 | ${({ theme }) => (theme.dark ? darkContainer : lightContainer)}; 11 | `; 12 | 13 | const darkContainer = css` 14 | background-color: #22272a; 15 | background-image: linear-gradient(145deg, rgba(255, 255, 255, 0.05) 0%, rgba(0, 0, 0, 0.5) 100%); 16 | box-shadow: inset 0 0 8px -1px rgba(0, 0, 0, 0.7), inset 0 0 4px 0 rgba(0, 0, 0, 0.8), 17 | -1px -1px 0px 0px rgba(0, 0, 0, 0.8), 1px 1px 0px 0px rgba(255, 255, 255, 0.1); 18 | `; 19 | 20 | const lightContainer = css` 21 | background: #ffffff; 22 | border-radius: 2px; 23 | border: 1px solid #d3d3d3; 24 | `; 25 | 26 | export const Digit = styled.div` 27 | padding: 8px 6px; 28 | box-sizing: border-box; 29 | display: inline-block; 30 | font-size: 14px; 31 | line-height: 16px; 32 | text-align: center; 33 | 34 | ${({ theme }) => (theme.dark ? darkDigit : lightDigit)}; 35 | `; 36 | 37 | const darkDigit = css` 38 | border-right: 1px solid rgba(0, 0, 0, 0.4); 39 | color: #fff; 40 | `; 41 | 42 | const lightDigit = css` 43 | color: #15181a; 44 | border-right: 1px solid #f2f2f2; 45 | `; 46 | 47 | export const ExponentialDigit = styled(Digit)` 48 | border: none; 49 | ${({ theme }) => 50 | theme.dark 51 | ? css` 52 | color: ${({ color, theme }) => color || theme.primary}; 53 | text-shadow: 0 0 2px rgba(0, 0, 0, 0.9), 54 | 0 0 9px ${({ color, theme }) => color || theme.primary}; 55 | ` 56 | : css` 57 | background: #f2f2f2; 58 | `}; 59 | `; 60 | -------------------------------------------------------------------------------- /src/styled/StopButton.styled.js: -------------------------------------------------------------------------------- 1 | import styled, { css } from 'styled-components'; 2 | 3 | import { light } from './constants'; 4 | 5 | export const Button = styled.button` 6 | outline: none; 7 | transition: all 0.1s ease-in; 8 | ${({ theme }) => (theme.dark ? darkButton : lightButton)}; 9 | 10 | &:disabled { 11 | opacity: ${({ theme }) => (theme.dark ? 1 : 0.65)}; 12 | cursor: not-allowed; 13 | } 14 | `; 15 | Button.defaultProps = { 16 | theme: light 17 | }; 18 | 19 | const lightButton = css` 20 | color: white; 21 | background-color: #ff5e5e; 22 | 23 | display: block; 24 | box-sizing: border-box; 25 | border: none; 26 | border-radius: 2px; 27 | font-weight: bold; 28 | font-size: 12px; 29 | text-transform: uppercase; 30 | padding: 0; 31 | width: ${({ size }) => `${size}px`}; 32 | min-height: ${({ size }) => `${size * 0.42}px`}; 33 | text-align: center; 34 | cursor: pointer; 35 | letter-spacing: 0.1; 36 | line-height: 1; 37 | 38 | &:hover, 39 | &:focus, 40 | &:active { 41 | color: #fff; 42 | } 43 | 44 | &:hover { 45 | background-color: #ff8585; 46 | } 47 | 48 | &:active { 49 | background-color: #e64545; 50 | } 51 | `; 52 | 53 | const darkButton = css` 54 | color: #ff6e6e; 55 | background-color: #22272a; 56 | 57 | text-shadow: 0 0 2px rgba(0, 0, 0, 0.9), 0 0 9px #ff6e6e; 58 | 59 | background-image: linear-gradient(145deg, rgba(255, 255, 255, 0.05) 0%, rgba(0, 0, 0, 0.5) 100%); 60 | box-shadow: inset 0 0 8px -1px rgba(0, 0, 0, 0.7), inset 0 0 4px 0 rgba(0, 0, 0, 0.8), 61 | -1px -1px 0px 0px rgba(0, 0, 0, 0.8), 1px 1px 0px 0px rgba(255, 255, 255, 0.1); 62 | 63 | display: block; 64 | box-sizing: border-box; 65 | border: none; 66 | border-radius: 2px; 67 | font-weight: bold; 68 | font-size: 12px; 69 | text-transform: uppercase; 70 | padding: 0; 71 | width: ${({ size }) => `${size}px`}; 72 | height: ${({ size }) => `${size * 0.42}px`}; 73 | text-align: center; 74 | cursor: pointer; 75 | letter-spacing: 0.1; 76 | line-height: 1; 77 | 78 | background-color: #22272a; 79 | color: #ff1a1a; 80 | 81 | &::before, 82 | &::after { 83 | transition: all 0.1s ease-in; 84 | background-color: #e03a3a; 85 | } 86 | 87 | &:hover::before, 88 | &:hover::after { 89 | background-color: #e64545; 90 | } 91 | 92 | &:active::before, 93 | &:active::after { 94 | background-color: #c72121; 95 | } 96 | 97 | &:hover::after, 98 | &:active::after, 99 | &:focus::after { 100 | box-shadow: none; 101 | } 102 | `; 103 | 104 | export default Button; 105 | -------------------------------------------------------------------------------- /src/styled/Tank.styled.js: -------------------------------------------------------------------------------- 1 | import styled, { css } from 'styled-components'; 2 | import Color from 'color'; 3 | 4 | import { light } from './constants'; 5 | 6 | export const TankContainer = styled.div` 7 | position: relative; 8 | width: ${({ width }) => `${width}px`}; 9 | height: ${({ height }) => `${height}px`}; 10 | z-index: 2; 11 | border-radius: ${({ thermometer }) => (thermometer ? '40px' : '0')}; 12 | 13 | ${({ theme }) => (theme.dark ? darkTankContainer : lightTankContainer)}; 14 | `; 15 | TankContainer.defaultProps = { 16 | theme: light 17 | }; 18 | 19 | const darkTankContainer = css` 20 | background-color: #22272a; 21 | background-image: linear-gradient(145deg, rgba(255, 255, 255, 0.05) 0%, rgba(0, 0, 0, 0.5) 100%); 22 | box-shadow: inset 0 0 8px -1px rgba(0, 0, 0, 0.7), inset 0 0 4px 0 rgba(0, 0, 0, 0.8), 23 | -1px -1px 0px 0px rgba(0, 0, 0, 0.8), 1px 1px 0px 0px rgba(255, 255, 255, 0.1); 24 | `; 25 | 26 | const lightTankContainer = css` 27 | background: ${props => props.theme.secondary}; 28 | `; 29 | 30 | export const TankFill = styled.div` 31 | position: absolute; 32 | bottom: 0; 33 | width: 100%; 34 | height: ${({ height }) => height || 0}; 35 | 36 | border-radius: ${({ thermometer }) => (thermometer ? '40px' : '0')}; 37 | border-radius: 0px; 38 | 39 | ${({ theme }) => (theme.dark ? darkTankFill : lightTankFill)}; 40 | `; 41 | TankFill.defaultProps = { 42 | theme: light 43 | }; 44 | 45 | const darkTankFill = css` 46 | background: ${({ color, theme }) => color || theme.primary}; 47 | background-image: linear-gradient(0deg, rgba(0, 0, 0, 0.7) 30%, rgba(255, 255, 255, 0.7) 100%); 48 | background-blend-mode: overlay; 49 | box-shadow: 0 0 6px 1px 50 | ${({ color, theme }) => 51 | Color(color || theme.primary) 52 | .alpha(0.7) 53 | .string()}; 54 | `; 55 | 56 | const lightTankFill = css` 57 | background: ${({ color, theme }) => color || theme.primary}; 58 | `; 59 | 60 | export const TickContainer = styled.div` 61 | position: relative; 62 | ${({ xPositioned }) => 63 | xPositioned && 64 | css` 65 | direction: rtl; 66 | `} display: flex; 67 | flex-direction: column; 68 | justify-content: space-between; 69 | margin-right: 4px; 70 | margin-top: -6px; 71 | margin-bottom: -6px; 72 | `; 73 | 74 | export const Tick = styled.div` 75 | ${({ xPosition }) => 76 | xPosition || xPosition === 0 77 | ? css` 78 | position: absolute; 79 | bottom: ${`calc(${xPosition}% - ${(xPosition / 100.0) * 18}px)`}; 80 | ` 81 | : ''} display: flex; 82 | align-items: center; 83 | justify-content: flex-end; 84 | height: 18px; 85 | color: ${props => props.color || (props.theme.dark ? '#ddd' : '#000')}; 86 | & .label { 87 | font-size: 12px; 88 | text-align: right; 89 | margin-right: 4px; 90 | white-space: nowrap; 91 | } 92 | 93 | & .tick { 94 | height: 1px; 95 | width: ${props => props.width || 4}px; 96 | background: ${props => props.theme.detail}; 97 | } 98 | `; 99 | 100 | Tick.defaultProps = { 101 | theme: light 102 | }; 103 | 104 | export const Container = styled.div` 105 | display: flex; 106 | flex-direction: row; 107 | justify-content: center; 108 | 109 | ${({ thermometer }) => 110 | thermometer 111 | ? css` 112 | margin-top: 8px; 113 | margin-left: ${({ xPositioned }) => (xPositioned ? '-4px' : '-24px')}; 114 | ` 115 | : ''}; 116 | `; 117 | 118 | export const ExceededWarning = styled.span` 119 | color: #dc3545; 120 | font-size: 0.8rem; 121 | text-align: center; 122 | display: block; 123 | `; 124 | -------------------------------------------------------------------------------- /src/styled/Thermometer.styled.js: -------------------------------------------------------------------------------- 1 | import styled from 'styled-components'; 2 | 3 | import { light } from './constants'; 4 | 5 | const WIDTH = 20; 6 | 7 | export const ThermometerContainer = styled.div` 8 | display: flex; 9 | flex-direction: column; 10 | align-items: center; 11 | `; 12 | 13 | export const Bulb = styled.div` 14 | width: ${1.5 * WIDTH}px; 15 | height: ${1.5 * WIDTH}px; 16 | border-radius: 50%; 17 | background-color: ${props => 18 | props.on ? props.color || props.theme.primary : props.theme.secondary}; 19 | position: absolute; 20 | left: 50%; 21 | transform: translateX(-50%); 22 | bottom: -${WIDTH}px; 23 | z-index: -1; 24 | `; 25 | 26 | Bulb.defaultProps = { 27 | theme: light 28 | }; 29 | 30 | export const CurrentValueContainer = styled.div` 31 | display: flex; 32 | width: 100%; 33 | flex-direction: column; 34 | align-items: center; 35 | text-align: center; 36 | 37 | & > div { 38 | margin-top: 56px; 39 | line-height: 28px; 40 | } 41 | `; 42 | 43 | CurrentValueContainer.defaultProps = { 44 | theme: light 45 | }; 46 | -------------------------------------------------------------------------------- /src/styled/constants.js: -------------------------------------------------------------------------------- 1 | export const colors = { 2 | PRIMARY: '#ABE2FB', 3 | SECONDARY: '#E6E6E6', 4 | DARKER_PRIMARY: '#87ceeb', 5 | OFF_WHITE: '#15181A', 6 | GREY: '#D3D3D3', 7 | RED: '#FF5E5E', 8 | DARK_GREY: '#535D63' 9 | }; 10 | 11 | export const TRACK_TOTAL_DEG = 270.0; 12 | 13 | export const RADIAN = Math.PI / 180.0; 14 | 15 | export const light = { 16 | primary: colors.PRIMARY, 17 | secondary: colors.SECONDARY, 18 | detail: colors.GREY, 19 | dark: false 20 | }; 21 | 22 | export const dark = { 23 | primary: colors.PRIMARY, 24 | secondary: colors.DARK_GREY, 25 | detail: colors.DARK_GREY, 26 | dark: true 27 | }; 28 | 29 | export default { 30 | dark, 31 | light, 32 | colors 33 | }; 34 | -------------------------------------------------------------------------------- /src/styled/shared/Indicator.styled.js: -------------------------------------------------------------------------------- 1 | import PropTypes from 'prop-types'; 2 | import styled, { css } from 'styled-components'; 3 | 4 | import { light } from '../constants'; 5 | 6 | const Indicator = styled('div')` 7 | border-radius: ${({ rectangular }) => (rectangular ? '0' : '50%')}; 8 | transition: all 100ms ease-in-out; 9 | ${props => { 10 | const color = props.main 11 | ? props.on 12 | ? props.primary || props.theme.primary 13 | : props.secondary || props.theme.secondary 14 | : props.on 15 | ? props.theme.secondary 16 | : props.primary || props.theme.primary; 17 | 18 | return css` 19 | width: ${props.width || props.height || props.size}px; 20 | height: ${props.height || props.width || props.size}px; 21 | background-color: ${color}; 22 | ${props.border ? `border: 1px solid ${props.on ? color : '#F8F4F4'};` : ''} 23 | ${props.theme.dark 24 | ? (props.on && props.main) || (!props.on && !props.main) 25 | ? css` 26 | box-shadow: 0 0 8px 2px ${color}, 1px 1px 0px 0px rgba(0, 0, 0, 0.9), 27 | -1px -1px 0px 0px rgba(255, 255, 255, 0.1); 28 | ` 29 | : css` 30 | background-image: linear-gradient( 31 | 145deg, 32 | rgba(255, 255, 255, 0.1) 0%, 33 | rgba(0, 0, 0, 0.5) 100% 34 | ); 35 | background-blend-mode: overlay; 36 | box-shadow: inset 0 0 8px -1px rgba(0, 0, 0, 0.5), inset 0 0 4px 0 rgba(0, 0, 0, 0.6), 37 | -1px -1px 0px 0px rgba(0, 0, 0, 0.9), 1px 1px 0px 0px rgba(255, 255, 255, 0.1); 38 | ` 39 | : ''} 40 | `; 41 | }} 42 | `; 43 | Indicator.defaultProps = { 44 | theme: light 45 | }; 46 | 47 | Indicator.propTypes = { 48 | /** 49 | * Size of the indicator 50 | */ 51 | size: PropTypes.number, 52 | 53 | /** 54 | * Theme for styling the component 55 | */ 56 | theme: PropTypes.object, 57 | 58 | /** 59 | * Add border for off 60 | */ 61 | border: PropTypes.bool, 62 | 63 | /** 64 | * Color to display when on 65 | */ 66 | primary: PropTypes.string, 67 | 68 | /** 69 | * Color to display when off 70 | */ 71 | secondary: PropTypes.string 72 | }; 73 | 74 | export default Indicator; 75 | -------------------------------------------------------------------------------- /src/styled/shared/Label.styled.js: -------------------------------------------------------------------------------- 1 | import styled, { css } from 'styled-components'; 2 | 3 | export default styled.label` 4 | display: block; 5 | font-size: 14px; 6 | ${({ position }) => 7 | position === 'top' 8 | ? css` 9 | margin-bottom: 8px; 10 | ` 11 | : css` 12 | margin-top: 8px; 13 | `} 14 | ${props => 15 | css` 16 | ${props.css} 17 | `} 18 | `; 19 | -------------------------------------------------------------------------------- /src/styled/shared/LabelContainer.styled.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import styled from 'styled-components'; 3 | 4 | import Label from './Label.styled'; 5 | 6 | const Container = styled.div` 7 | display: flex; 8 | align-items: center; 9 | justify-content: space-around; 10 | flex-direction: column; 11 | ${({ fullSize }) => { 12 | if (fullSize) return 'width: 100%;'; 13 | return ''; 14 | }} 15 | `; 16 | 17 | function LabelContainer(props) { 18 | let labelText = props.label; 19 | let customLabelStyle = {}; 20 | if (typeof props.label === 'object') { 21 | labelText = props.label.label; 22 | customLabelStyle = props.label.style; 23 | } 24 | const labelElement = 27 | // if (labelText && labelText.length) { 28 | return ( 29 | 30 | {props.labelPosition == 'top' && labelElement} 31 | {props.children} 32 | {props.labelPosition != 'top' && labelElement} 33 | 34 | ); 35 | // } 36 | // return
{props.children}
; 37 | } 38 | 39 | LabelContainer.defaultProps = { 40 | labelPosition: 'bottom' 41 | }; 42 | 43 | export default LabelContainer; 44 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const WebpackDashDynamicImport = require('@plotly/webpack-dash-dynamic-import'); 3 | 4 | const packagejson = require('./package.json'); 5 | 6 | const dashLibraryName = packagejson.name.replace(/-/, '_'); 7 | 8 | module.exports = (env, argv) => { 9 | 10 | let mode; 11 | 12 | const overrides = module.exports || {}; 13 | 14 | // if user specified mode flag take that value 15 | if (argv && argv.mode) { 16 | mode = argv.mode; 17 | } 18 | 19 | // else if configuration object is already set (module.exports) use that value 20 | else if (overrides.mode) { 21 | mode = overrides.mode; 22 | } 23 | 24 | // else take webpack default (production) 25 | else { 26 | mode = 'production'; 27 | } 28 | 29 | let filename = (overrides.output || {}).filename; 30 | if (!filename) { 31 | const modeSuffix = mode === 'development' ? 'dev' : 'min'; 32 | filename = `${dashLibraryName}.${modeSuffix}.js`; 33 | } 34 | 35 | const entry = overrides.entry || { main: './src/index.js' }; 36 | 37 | const devtool = overrides.devtool || 'source-map'; 38 | 39 | const externals = ('externals' in overrides) ? overrides.externals : ({ 40 | react: 'React', 41 | 'react-dom': 'ReactDOM', 42 | 'plotly.js': 'Plotly', 43 | 'prop-types': 'PropTypes' 44 | }); 45 | 46 | return { 47 | mode, 48 | entry, 49 | output: { 50 | path: path.resolve(__dirname, dashLibraryName), 51 | chunkFilename: '[name].js', 52 | filename, 53 | library: dashLibraryName, 54 | libraryTarget: 'window' 55 | }, 56 | externals, 57 | module: { 58 | rules: [ 59 | { 60 | test: /\.js$/, 61 | exclude: /node_modules/, 62 | use: { 63 | loader: 'babel-loader' 64 | } 65 | }, 66 | { 67 | test: /\.css$/, 68 | use: [ 69 | { 70 | loader: 'style-loader', 71 | options: { 72 | insert: function insertAtTop(element) { 73 | document.head.insertBefore(element, document.head.firstElementChild); 74 | }, 75 | }, 76 | }, 77 | { 78 | loader: 'css-loader' 79 | } 80 | ] 81 | } 82 | ] 83 | }, 84 | devtool, 85 | optimization: { 86 | splitChunks: { 87 | name: true, 88 | cacheGroups: { 89 | async: { 90 | chunks: 'async', 91 | minSize: 0, 92 | name(module, chunks, cacheGroupKey) { 93 | return `${cacheGroupKey}-${chunks[0].name}`; 94 | } 95 | } 96 | } 97 | } 98 | }, 99 | plugins: [ 100 | new WebpackDashDynamicImport() 101 | ] 102 | } 103 | }; 104 | --------------------------------------------------------------------------------