Skip to content

Commit c852db9

Browse files
authored
Feature/accept all colours (#506)
* Move list of colours to a new location * Ignore yarn lock files * update Navbar Simple component * add Bootstrap Color list * Update Card component * update more components * fix ListGroupItem * Update all components which require backgroundColor change * Update text-based components * run formatting * run npm install * fix outline buttons * fix default button * fix dropdowns * tidy up colour lists * add tests for custom colours * run formatting * Revert package lock file * revert package.json * add custom logic for hover controls * revert gitignore * Revert "add custom logic for hover controls" This reverts commit 2f31bb2. * revert button component due to problems with setting hover colour * Test using alert rather than button * revert button tests
1 parent 373d964 commit c852db9

File tree

15 files changed

+144
-69
lines changed

15 files changed

+144
-69
lines changed

src/components/Alert.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import React, {useEffect, useRef} from 'react';
22
import PropTypes from 'prop-types';
33
import {omit} from 'ramda';
44
import {Alert as RSAlert} from 'reactstrap';
5+
import {bootstrapColors} from '../private/BootstrapColors';
56

67
/**
78
* Alert allows you to create contextual feedback messages on user actions.
@@ -17,6 +18,8 @@ const Alert = props => {
1718
is_open,
1819
loading_state,
1920
setProps,
21+
color,
22+
style,
2023
...otherProps
2124
} = props;
2225

@@ -39,10 +42,13 @@ const Alert = props => {
3942
}
4043
};
4144

45+
const isBootstrapColor = bootstrapColors.has(color);
4246
return (
4347
<RSAlert
4448
isOpen={is_open}
4549
toggle={dismissable && dismiss}
50+
color={isBootstrapColor ? color : null}
51+
style={!isBootstrapColor ? {backgroundColor: color, ...style} : style}
4652
{...omit(['setProps'], otherProps)}
4753
data-dash-is-loading={
4854
(loading_state && loading_state.is_loading) || undefined
@@ -90,7 +96,9 @@ Alert.propTypes = {
9096

9197
/**
9298
* Alert color, options: primary, secondary, success, info, warning, danger,
93-
* link. Default: secondary.
99+
* link or any valid CSS color of
100+
* your choice (e.g. a hex code, a decimal code or a CSS color name)
101+
* Default: secondary.
94102
*/
95103
color: PropTypes.string,
96104

src/components/Badge.js

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,21 @@ import PropTypes from 'prop-types';
33
import {omit} from 'ramda';
44
import {Badge as RSBadge} from 'reactstrap';
55
import Link from '../private/Link';
6+
import {bootstrapColors} from '../private/BootstrapColors';
67

78
/**
89
* Badges can be used to add counts or labels to other components.
910
*/
1011
const Badge = props => {
11-
const {children, href, loading_state, setProps, ...otherProps} = props;
12+
const {
13+
children,
14+
href,
15+
loading_state,
16+
setProps,
17+
color,
18+
style,
19+
...otherProps
20+
} = props;
1221

1322
const incrementClicks = () => {
1423
if (setProps) {
@@ -18,13 +27,16 @@ const Badge = props => {
1827
});
1928
}
2029
};
30+
const isBootstrapColor = bootstrapColors.has(color);
2131

2232
otherProps[href ? 'preOnClick' : 'onClick'] = incrementClicks;
2333

2434
return (
2535
<RSBadge
2636
tag={href && Link}
2737
href={href}
38+
color={isBootstrapColor ? color : null}
39+
style={!isBootstrapColor ? {backgroundColor: color, ...style} : style}
2840
{...omit(['setProps', 'n_clicks', 'n_clicks_timestamp'], otherProps)}
2941
data-dash-is-loading={
3042
(loading_state && loading_state.is_loading) || undefined
@@ -72,7 +84,9 @@ Badge.propTypes = {
7284

7385
/**
7486
* Badge color, options: primary, secondary, success, info, warning, danger,
75-
* link. Default: secondary.
87+
* link or any valid CSS color of
88+
* your choice (e.g. a hex code, a decimal code or a CSS color name)
89+
* Default: secondary.
7690
*/
7791
color: PropTypes.string,
7892

src/components/Label.js

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import PropTypes from 'prop-types';
33
import {omit} from 'ramda';
44
import {Label as RSLabel} from 'reactstrap';
55
import classNames from 'classnames';
6+
import {bootstrapTextColors} from '../private/BootstrapColors';
67

78
const alignMap = {
89
start: 'align-self-start',
@@ -24,10 +25,13 @@ const Label = props => {
2425
xs,
2526
className,
2627
color,
28+
style,
2729
loading_state,
2830
...otherProps
2931
} = props;
3032

33+
const isBootstrapColor = bootstrapTextColors.has(color);
34+
3135
// check if column width has been specified, use alignment attribute if so
3236
const cols = colWidths.filter(
3337
colWidth => props[colWidth] || props[colWidth] === ''
@@ -37,14 +41,15 @@ const Label = props => {
3741
const classes = classNames(
3842
className,
3943
cols.length && alignClass,
40-
color && `text-${color}`
44+
color && isBootstrapColor && `text-${color}`
4145
);
4246

4347
return (
4448
<RSLabel
4549
for={html_for}
4650
xs={xs || width}
4751
className={classes}
52+
style={!isBootstrapColor ? {color: color, ...style} : style}
4853
{...omit(['setProps'], otherProps)}
4954
data-dash-is-loading={
5055
(loading_state && loading_state.is_loading) || undefined
@@ -173,7 +178,8 @@ Label.propTypes = {
173178

174179
/**
175180
* Text color, options: primary, secondary, success, warning, danger, info,
176-
* muted, light, dark, body, white, black-50, white-50.
181+
* muted, light, dark, body, white, black-50, white-50 or any valid CSS color of
182+
* your choice (e.g. a hex code, a decimal code or a CSS color name).
177183
*/
178184
color: PropTypes.string,
179185

src/components/Progress.js

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import React from 'react';
22
import PropTypes from 'prop-types';
33
import {omit} from 'ramda';
44
import {Progress as RSProgress} from 'reactstrap';
5+
import {bootstrapColors} from '../private/BootstrapColors';
56

67
const CustomProgressTag = props => {
78
// This is a little trick to enable us to pass styles to the outer div
@@ -14,15 +15,26 @@ const CustomProgressTag = props => {
1415
* progress with a callback and the `value` prop.
1516
*/
1617
const Progress = props => {
17-
const {children, loading_state, bar_style, style, ...otherProps} = props;
18+
const {
19+
children,
20+
loading_state,
21+
bar_style,
22+
color,
23+
style,
24+
...otherProps
25+
} = props;
26+
const isBootstrapColor = bootstrapColors.has(color);
1827
return (
1928
<RSProgress
2029
{...omit(['setProps'], otherProps)}
2130
data-dash-is-loading={
2231
(loading_state && loading_state.is_loading) || undefined
2332
}
2433
// reactstrap handles these inconsistently atm, have to swap around
25-
style={bar_style}
34+
color={isBootstrapColor ? color : null}
35+
style={
36+
!isBootstrapColor ? {backgroundColor: color, ...bar_style} : bar_style
37+
}
2638
outer_style={style}
2739
tag={CustomProgressTag}
2840
>
@@ -98,7 +110,8 @@ Progress.propTypes = {
98110

99111
/**
100112
* Set color of the progress bar, options: primary, secondary, success,
101-
* warning, danger, info.
113+
* warning, danger, info or any valid CSS color
114+
* of your choice (e.g. a hex code, a decimal code or a CSS color name).
102115
*/
103116
color: PropTypes.string,
104117

src/components/Spinner.js

Lines changed: 4 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,7 @@ import React, {Fragment} from 'react';
22
import PropTypes from 'prop-types';
33
import {omit, type} from 'ramda';
44
import {Spinner as RSSpinner} from 'reactstrap';
5-
6-
const spinnerColors = new Set([
7-
'primary',
8-
'light',
9-
'dark',
10-
'secondary',
11-
'success',
12-
'warning',
13-
'danger',
14-
'info',
15-
'body',
16-
'muted',
17-
'black-50',
18-
'white-50',
19-
'white'
20-
]);
5+
import {bootstrapColors} from '../private/BootstrapColors';
216

227
/**
238
* Render Bootstrap style loading spinners using only CSS.
@@ -39,7 +24,7 @@ const Spinner = props => {
3924
...otherProps
4025
} = props;
4126

42-
const isSpinnerColor = spinnerColors.has(color);
27+
const isBootstrapColor = bootstrapColors.has(color);
4328

4429
const fullscreenStyle = {
4530
position: 'fixed',
@@ -58,8 +43,8 @@ const Spinner = props => {
5843

5944
const SpinnerDiv = style => (
6045
<RSSpinner
61-
color={isSpinnerColor ? color : null}
62-
style={{color: !isSpinnerColor && color, ...style}}
46+
color={isBootstrapColor ? color : null}
47+
style={{color: !isBootstrapColor && color, ...style}}
6348
className={spinnerClassName}
6449
{...omit(['setProps'], otherProps)}
6550
/>

src/components/__tests__/Alert.test.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,14 @@ describe('Alert', () => {
3939
expect(alertDark).toHaveClass('alert-dark');
4040
});
4141

42+
test('applies custom color with "color" prop', () => {
43+
const {
44+
container: {firstChild: alert}
45+
} = render(<Alert color="#FA7268" />);
46+
47+
expect(alert).toHaveStyle('background-color: #FA7268;');
48+
});
49+
4250
test('renders a dismiss button with dismissable=true', () => {
4351
const alertDismissable = render(<Alert dismissable />);
4452

src/components/__tests__/Label.test.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,4 +47,13 @@ describe('Label', () => {
4747
expect(labelSuccess).toHaveClass('text-success');
4848
expect(labelDark).toHaveClass('text-dark');
4949
});
50+
51+
test('applies custom color with "color" prop', () => {
52+
const {
53+
container: {firstChild: button}
54+
} = render(<Label color="#FA7268" />);
55+
56+
expect(button).toHaveStyle('color: #FA7268;');
57+
});
58+
5059
});

src/components/card/Card.js

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ import React from 'react';
22
import PropTypes from 'prop-types';
33
import {omit} from 'ramda';
44
import {Card as RSCard} from 'reactstrap';
5+
import {bootstrapColors} from '../../private/BootstrapColors';
6+
57

68
/**
79
* Component for creating Bootstrap cards. Use in conjunction with CardBody,
@@ -10,12 +12,15 @@ import {Card as RSCard} from 'reactstrap';
1012
* options.
1113
*/
1214
const Card = props => {
13-
const {children, loading_state, ...otherProps} = props;
15+
const {children, color, style, loading_state, ...otherProps} = props;
16+
const isBootstrapColor = bootstrapColors.has(color);
1417
return (
1518
<RSCard
1619
data-dash-is-loading={
1720
(loading_state && loading_state.is_loading) || undefined
1821
}
22+
color={isBootstrapColor ? color : null}
23+
style={!isBootstrapColor ? {backgroundColor: color, ...style} : style}
1924
{...omit(['setProps'], otherProps)}
2025
>
2126
{children}
@@ -55,7 +60,9 @@ Card.propTypes = {
5560

5661
/**
5762
* Card color, options: primary, secondary, success, info, warning, danger,
58-
* light, dark. Default is light.
63+
* light, dark or any valid CSS color of
64+
* your choice (e.g. a hex code, a decimal code or a CSS color name).
65+
* Default is light.
5966
*/
6067
color: PropTypes.string,
6168

src/components/dropdownmenu/DropdownMenu.js

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import {omit} from 'ramda';
44
import {Dropdown, DropdownToggle} from 'reactstrap';
55
import {DropdownMenu as RSDropdownMenu} from 'reactstrap';
66
import {DropdownMenuContext} from '../../private/DropdownMenuContext';
7+
import {bootstrapColors} from '../../private/BootstrapColors';
78

89
/**
910
* DropdownMenu creates an overlay useful for grouping together links and other
@@ -28,7 +29,7 @@ const DropdownMenu = props => {
2829
} = props;
2930

3031
const [dropdownOpen, setDropdownOpen] = useState(false);
31-
32+
const isBootstrapColor = bootstrapColors.has(color);
3233
const toggle = () => {
3334
if (!disabled) {
3435
setDropdownOpen(!dropdownOpen);
@@ -59,8 +60,8 @@ const DropdownMenu = props => {
5960
nav={nav}
6061
caret={caret}
6162
disabled={disabled}
62-
color={color}
63-
style={toggle_style}
63+
color={isBootstrapColor ? color : undefined}
64+
style={!isBootstrapColor ? {backgroundColor: color, ...toggle_style} : toggle_style}
6465
className={toggleClassName}
6566
>
6667
{label}
@@ -152,7 +153,9 @@ DropdownMenu.propTypes = {
152153

153154
/**
154155
* Set the color of the DropdownMenu toggle. Available options are: 'primary',
155-
* 'secondary', 'success', 'warning', 'danger', 'info', 'link'. Default: 'secondary'
156+
* 'secondary', 'success', 'warning', 'danger', 'info', 'link' or any valid CSS
157+
* color of your choice (e.g. a hex code, a decimal code or a CSS color name)
158+
* Default: 'secondary'
156159
*/
157160
color: PropTypes.string,
158161

src/components/form/FormText.js

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,18 @@ import React from 'react';
22
import PropTypes from 'prop-types';
33
import {omit} from 'ramda';
44
import {FormText as RSFormText} from 'reactstrap';
5+
import {bootstrapTextColors} from '../../private/BootstrapColors';
56

67
/**
78
* Add explanatory text below your input components.
89
*/
910
const FormText = props => {
10-
const {children, loading_state, ...otherProps} = props;
11+
const {children, loading_state, color, style, ...otherProps} = props;
12+
const isBootstrapColor = bootstrapTextColors.has(color);
1113
return (
1214
<RSFormText
15+
color={isBootstrapColor ? color : null}
16+
style={!isBootstrapColor ? {color: color, ...style} : style}
1317
{...omit(['setProps'], otherProps)}
1418
data-dash-is-loading={
1519
(loading_state && loading_state.is_loading) || undefined
@@ -52,7 +56,8 @@ FormText.propTypes = {
5256

5357
/**
5458
* Text color, options: primary, secondary, success, warning, danger, info,
55-
* muted, light, dark, body, white, black-50, white-50.
59+
* muted, light, dark, body, white, black-50, white-50 or any valid CSS color of
60+
* your choice (e.g. a hex code, a decimal code or a CSS color name).
5661
*/
5762
color: PropTypes.string,
5863

0 commit comments

Comments
 (0)