Skip to content

Commit afa2e36

Browse files
Shammamah HossainMarc-Andre-Rivetalexcjohnson
authored
Add descriptive class names to DAQ components. (#80)
* Add helpers to generate DAQ class names and remove id, className, and setProps. * Unpack BooleanSwitch props. * Add generated class names to ColorPicker. * Add generated class names to Gauge. * Add theme to GraduatedBar. * Add generated class names to GraduatedBar. * Unpack Indicator props. * Add generated class names to Indicator. * Add generated class names to Joystick. * Unpack Knob props. * Add generated class names to Knob. * Add generated class names to LEDDisplay. * Unpack NumericInput props. * Add generated class names to NumericInput. * Unpack PowerButton props. * Add generated class names to PowerButton. * Unpack PrecisionInput props. * Change background color of PrecisionInput when in dark mode. * Add generated class names to PrecisionInput. * Add theme to Tank. * Add generated class names to Tank. * Add generated class names to Thermometer. * Unpack ToggleSwitch props. * Add generated class names to ToggleSwitch. * Add theme to StopButton. * Unpack StopButton props; add generated class names to StopButton. * Add generated class names to Slider. * Add class names to LEDDisplay digits. * Fix styles for dark theme buttons, digits, and tank. * Fix tests. * Remove unused prop. * Update src/components/Gauge.react.js Co-Authored-By: alexcjohnson <[email protected]> * Improve className hygiene. * Move Gauge prop. * Declare only the applicable PrecisionInput/Output. * Update version. * Add auto-generated files. * Update CHANGELOG. Co-authored-by: Marc-André Rivet <[email protected]> Co-authored-by: alexcjohnson <[email protected]>
1 parent aa5950c commit afa2e36

33 files changed

+431
-175
lines changed

CHANGELOG.md

+8-1
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,16 @@ The format is based on [Keep a
66
Changelog](http://keepachangelog.com/en/1.0.0/) and this project
77
adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
88

9-
## [Unreleased]
9+
## [0.4.0] - 2020-03-04
10+
### Added
11+
* [#80](https://github.com/plotly/dash-daq/pull/80) Added `theme` prop to `GraduatedBar` component.
12+
1013
### Changed
1114
* [#91](https://github.com/plotly/dash-daq/pull/91) Renamed async modules with hyphen `-` instead of tilde `~`
15+
* [#80](https://github.com/plotly/dash-daq/pull/80) Changed class names for components according to BEM conventions.
16+
17+
### Fixed
18+
* [#80](https://github.com/plotly/dash-daq/pull/80) Fixed color problems for dark-theme buttons and inputs.
1219

1320
## [0.3.3] - 2020-01-23
1421
### Changed

dash_daq/GraduatedBar.py

+4-3
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ class GraduatedBar(Component):
3232
- step (number; default 0.5): Value by which progress blocks appear
3333
- showCurrentValue (boolean; optional): If true, the current percentage
3434
of the bar will be displayed
35+
- theme (dict; default light): Theme configuration to be set by a ThemeProvider
3536
- label (dict; optional): Description to be displayed alongside the control. To control styling, pass an object with label and style properties. label has the following type: string | dict containing keys 'style', 'label'.
3637
Those keys have the following types:
3738
- style (dict; optional)
@@ -40,12 +41,12 @@ class GraduatedBar(Component):
4041
- className (string; optional): Class to apply to the root component element.
4142
- style (dict; optional): Style to apply to the root component element."""
4243
@_explicitize_args
43-
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, label=Component.UNDEFINED, labelPosition=Component.UNDEFINED, className=Component.UNDEFINED, style=Component.UNDEFINED, **kwargs):
44-
self._prop_names = ['id', 'value', 'color', 'size', 'vertical', 'min', 'max', 'step', 'showCurrentValue', 'label', 'labelPosition', 'className', 'style']
44+
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):
45+
self._prop_names = ['id', 'value', 'color', 'size', 'vertical', 'min', 'max', 'step', 'showCurrentValue', 'theme', 'label', 'labelPosition', 'className', 'style']
4546
self._type = 'GraduatedBar'
4647
self._namespace = 'dash_daq'
4748
self._valid_wildcard_attributes = []
48-
self.available_properties = ['id', 'value', 'color', 'size', 'vertical', 'min', 'max', 'step', 'showCurrentValue', 'label', 'labelPosition', 'className', 'style']
49+
self.available_properties = ['id', 'value', 'color', 'size', 'vertical', 'min', 'max', 'step', 'showCurrentValue', 'theme', 'label', 'labelPosition', 'className', 'style']
4950
self.available_wildcard_properties = []
5051

5152
_explicit_args = kwargs.pop('_explicit_args')

dash_daq/async-colorpicker.js

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dash_daq/async-colorpicker.js.map

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dash_daq/async-slider.js

+3-3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dash_daq/async-slider.js.map

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dash_daq/dash_daq.min.js

+3-3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dash_daq/dash_daq.min.js.map

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dash_daq/package-info.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "dash-daq",
3-
"version": "0.3.3",
3+
"version": "0.4.0",
44
"engines": {
55
"node": ">=8"
66
},

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "dash-daq",
3-
"version": "0.3.3",
3+
"version": "0.4.0",
44
"engines": {
55
"node": ">=8"
66
},

src/components/BooleanSwitch.react.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,14 @@ class BooleanSwitch extends Component {
3030
}
3131

3232
render() {
33+
const { color, theme } = this.props;
3334
return (
3435
<ToggleSwitch
3536
{...this.props}
3637
value={this.state.on}
3738
setProps={this.setPropsOverride}
3839
booleanSwitch={true}
39-
color={this.props.color || this.props.theme.primary}
40+
color={color || theme.primary}
4041
/>
4142
);
4243
}

src/components/Gauge.react.js

+15-4
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ import log from '../helpers/logarithm';
1313
import generateScale from '../helpers/scale';
1414
import { getColorValue } from '../helpers/colorRanges';
1515

16+
import { getClassName, getFilteredProps } from '../helpers/classNameGenerator';
17+
1618
/**
1719
* A Gauge component that points to
1820
* a value between some range.
@@ -34,7 +36,8 @@ class Gauge extends React.Component {
3436
base,
3537
id,
3638
className,
37-
style
39+
style,
40+
theme
3841
} = this.props;
3942

4043
const colorValue = getColorValue(color);
@@ -48,24 +51,32 @@ class Gauge extends React.Component {
4851

4952
const progress = computeProgress({ min, max, value, progressionTarget: 1 });
5053

54+
const elementName = getClassName('gauge', theme);
55+
5156
const currentValue = (
5257
<CurrentValue
58+
className={elementName + '__current-value'}
5359
valueColor={colorValue}
5460
units={units}
5561
css={'transform: translateY(-150%); top: 0;'}
5662
>
5763
{logarithmic ? log.formatValue(value, base) : value.toFixed(1)}
5864
</CurrentValue>
5965
);
66+
const filteredProps = getFilteredProps(this.props);
6067

6168
return (
62-
<div id={id} className={className} style={style}>
69+
<div id={id} className={elementName + (className ? ' ' + className : '')} style={style}>
6370
<LabelContainer
64-
{...this.props}
71+
className={elementName + '__label'}
72+
{...filteredProps}
6573
labelCSS={this.props.labelPosition === 'top' ? null : 'transform: translateY(-80px);'}
6674
>
6775
<Container color={colorValue}>
68-
<GaugeSVG {...{ ...this.props, scale }} progress={progress} />
76+
<GaugeSVG
77+
className={elementName + '__gauge'}
78+
{...{ ...filteredProps, scale, progress }}
79+
/>
6980
{showCurrentValue && currentValue}
7081
</Container>
7182
</LabelContainer>

src/components/GraduatedBar.react.js

+35-8
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
import React from 'react';
22
import PropTypes from 'prop-types';
33

4+
import { withTheme } from 'styled-components';
45
import { light } from '../styled/constants';
56
import { getColorValue, isContiguous, getGradientObject } from '../helpers/colorRanges';
67
import { Container, Block, Value } from '../styled/GraduatedBar.styled';
78
import LabelContainer from '../styled/shared/LabelContainer.styled';
89

10+
import { getClassName, getFilteredProps } from '../helpers/classNameGenerator';
11+
912
const valueColor = (value, color) => {
1013
const entry = Object.entries(color.ranges).filter(
1114
([, range]) => value >= range[0] && value <= range[1]
@@ -32,7 +35,8 @@ const GraduatedBar = props => {
3235
size,
3336
style,
3437
showCurrentValue,
35-
vertical
38+
vertical,
39+
theme
3640
} = props;
3741
const value = props.value || min;
3842

@@ -44,27 +48,44 @@ const GraduatedBar = props => {
4448
gradient = getGradientObject({ color, min, max });
4549
}
4650

51+
const elementName = getClassName('graduatedbar', theme);
52+
const filteredProps = getFilteredProps(props);
53+
4754
for (let i = min; i < normalizedValue; i += step) {
48-
let blockProps = { ...props, color: getColorValue(color) };
55+
let blockProps = { ...filteredProps, color: getColorValue(color) };
4956

5057
if (color.ranges && valueColor(i, color)) {
51-
blockProps = { ...props, color: valueColor(i, color) };
58+
blockProps = { ...filteredProps, color: valueColor(i, color) };
5259
}
5360

5461
progressBlocks.push(
55-
<Block key={i} progress={i / (max - min)} gradient={gradient} {...blockProps} />
62+
<Block
63+
className={elementName + '__progressBlock'}
64+
key={i}
65+
progress={i / (max - min)}
66+
gradient={gradient}
67+
{...blockProps}
68+
/>
5669
);
5770
}
5871

5972
let percent = (normalizedValue / (max - min)) * 100;
6073
if (!isFinite(percent)) percent = 0;
6174

6275
return (
63-
<div id={id} className={className} style={style}>
64-
<LabelContainer label={label} labelPosition={labelPosition}>
76+
<div id={id} className={elementName + (className ? ' ' + className : '')} style={style}>
77+
<LabelContainer
78+
className={elementName + '__label'}
79+
label={label}
80+
labelPosition={labelPosition}
81+
>
6582
<Container vertical={vertical} size={size}>
6683
{progressBlocks}
67-
{showCurrentValue && <Value vertical={vertical}>{percent.toFixed(0)}%</Value>}
84+
{showCurrentValue && (
85+
<Value className={elementName + '__currentvalue'} vertical={vertical}>
86+
{percent.toFixed(0)}%
87+
</Value>
88+
)}
6889
</Container>
6990
</LabelContainer>
7091
</div>
@@ -76,6 +97,7 @@ GraduatedBar.defaultProps = {
7697
max: 10,
7798
size: 250,
7899
step: 0.5,
100+
theme: light,
79101
labelPosition: 'top',
80102
color: light.primary
81103
};
@@ -157,6 +179,11 @@ GraduatedBar.propTypes = {
157179
*/
158180
showCurrentValue: PropTypes.bool,
159181

182+
/**
183+
* Theme configuration to be set by a ThemeProvider
184+
*/
185+
theme: PropTypes.object,
186+
160187
/**
161188
* Description to be displayed alongside the control. To control styling, pass an object with label and style properties.
162189
*/
@@ -191,4 +218,4 @@ GraduatedBar.propTypes = {
191218
style: PropTypes.object
192219
};
193220

194-
export default GraduatedBar;
221+
export default withTheme(GraduatedBar);

src/components/Indicator.react.js

+20-11
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,44 @@
11
import React from 'react';
22
import PropTypes from 'prop-types';
3-
import color from 'color';
3+
import convertColor from 'color';
44
import { withTheme } from 'styled-components';
55

66
import IndicatorLight from '../styled/shared/Indicator.styled';
7+
78
import LabelContainer from '../styled/shared/LabelContainer.styled';
89

910
import { colors, light } from '../styled/constants';
1011

12+
import { getClassName, getFilteredProps } from '../helpers/classNameGenerator';
13+
1114
/**
1215
* A boolean indicator LED.
1316
*/
1417
const Indicator = props => {
15-
const bg = color(props.color)
18+
const { id, className, color, size, width, height, value, style, theme } = props;
19+
20+
const bg = convertColor(color)
1621
.desaturate(0.2)
1722
.lighten(0.2)
1823
.rgb()
1924
.toString();
2025

26+
const elementName = getClassName('indicator', theme);
27+
const filteredProps = getFilteredProps(props);
28+
2129
return (
22-
<div id={props.id} className={props.className} style={props.style}>
23-
<LabelContainer {...props}>
30+
<div id={id} className={elementName + (className ? ' ' + className : '')} style={style}>
31+
<LabelContainer {...filteredProps}>
2432
<IndicatorLight
25-
size={props.size}
26-
width={props.width}
27-
height={props.height}
28-
rectangular={props.width && props.height}
33+
className={elementName + '__indicator' + (props.value ? '--on' : '--off')}
34+
size={size}
35+
width={width}
36+
height={height}
37+
rectangular={width && height}
2938
main={true}
30-
on={props.value}
31-
primary={props.color}
32-
secondary={!props.theme.dark ? bg : null}
39+
on={value}
40+
primary={color}
41+
secondary={!theme.dark ? bg : null}
3342
/>
3443
</LabelContainer>
3544
</div>

src/components/Joystick.react.js

+10-3
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,12 @@ import React, { Component } from 'react';
22
import PropTypes from 'prop-types';
33
import { withTheme } from 'styled-components';
44
import joystick from 'nipplejs';
5+
56
import { light } from '../styled/constants';
67
import LabelContainer from '../styled/shared/LabelContainer.styled';
78

9+
import { getClassName, getFilteredProps } from '../helpers/classNameGenerator';
10+
811
/**
912
* A joystick.
1013
*/
@@ -51,12 +54,16 @@ class Joystick extends Component {
5154
}
5255

5356
render() {
54-
const { id, className, style, size } = this.props;
57+
const { id, className, style, size, theme } = this.props;
58+
59+
const elementName = getClassName('joystick', theme);
60+
const filteredProps = getFilteredProps(this.props);
5561

5662
return (
57-
<div id={id} className={className} style={style}>
58-
<LabelContainer {...this.props}>
63+
<div id={id} className={elementName + (className ? ' ' + className : '')} style={style}>
64+
<LabelContainer className={elementName + '__label'} {...filteredProps}>
5965
<div
66+
className={elementName + '__joystick'}
6067
ref={ref => (this.zoneRef = ref)}
6168
style={{
6269
position: 'relative',

src/components/Knob.react.js

+15-8
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ import { computeProgress, roundToDecimal } from '../helpers/util';
1010
import { getColorValue } from '../helpers/colorRanges';
1111
import generateScale from '../helpers/scale';
1212

13+
import { getClassName, getFilteredProps } from '../helpers/classNameGenerator';
14+
1315
const RESET_START_ANGLE = -1;
1416

1517
const valueToDeg = ({ min, max, value }) =>
@@ -125,23 +127,28 @@ class Knob extends Component {
125127

126128
render() {
127129
const { min, max, value } = this.state;
130+
const { id, className, labelPosition, color, style, disabled, theme } = this.props;
128131
const progress = computeProgress({ min, max, value, progressionTarget: 1 });
129132

133+
const elementName = getClassName('knob', theme);
134+
const filteredProps = getFilteredProps(this.props);
135+
130136
return (
131-
<div id={this.props.id} className={this.props.className} style={this.props.style}>
137+
<div id={id} className={elementName + (className ? ' ' + className : '')} style={style}>
132138
<LabelContainer
133-
{...this.props}
134-
labelCSS={this.props.labelPosition === 'top' ? null : 'transform: translateY(-40px);'}
139+
className={elementName + '__label'}
140+
{...filteredProps}
141+
labelCSS={labelPosition === 'top' ? null : 'transform: translateY(-40px);'}
135142
>
136-
<Container color={getColorValue(this.props.color)}>
143+
<Container className={elementName + '__container'} color={getColorValue(color)}>
137144
<KnobSvg
138145
progress={progress}
139-
{...this.props}
146+
{...filteredProps}
140147
{...this.state}
141148
refFunc={ele => (this.knobElement = ele)}
142-
onMouseDown={this.props.disabled ? this.noop : this.onMouseDown}
143-
onMouseUp={this.props.disabled ? this.noop : this.onMouseUp}
144-
onMouseMove={this.props.disabled ? this.noop : this.onMouseMove}
149+
onMouseDown={disabled ? this.noop : this.onMouseDown}
150+
onMouseUp={disabled ? this.noop : this.onMouseUp}
151+
onMouseMove={disabled ? this.noop : this.onMouseMove}
145152
/>
146153
</Container>
147154
</LabelContainer>

0 commit comments

Comments
 (0)