Skip to content

Commit a65045f

Browse files
committed
fix(Button): Fixed disabled and icon styles
1 parent 2e71f38 commit a65045f

File tree

4 files changed

+143
-89
lines changed

4 files changed

+143
-89
lines changed

src/components/Button/Button.tsx

Lines changed: 53 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -4,56 +4,70 @@ import {
44
ButtonProps,
55
DynamicIcon,
66
} from '@bluebase/components';
7+
import { getButtonColors, styles } from './styles';
78

89
import MUIButton from '@material-ui/core/Button';
910
import React from 'react';
1011
import { StyleSheet } from 'react-native';
1112
import { componentMapper } from '@bluebase/component-mapper';
12-
import { styles } from './styles';
1313
import { withPropsStyles } from '../../withPropsStyles';
14+
import { withTheme } from '@material-ui/core/styles';
1415

1516
export const Button = withPropsStyles(styles)(
16-
componentMapper<ButtonProps>(MUIButton, {
17-
children: ({ title, children, loading, icon }: ButtonProps) => {
18-
const content = children ? children : title;
17+
withTheme()(
18+
componentMapper<ButtonProps>(MUIButton, {
19+
children: (props: ButtonProps) => {
20+
const { title, children, loading, icon, bluebaseTheme } = props;
21+
const content = children ? children : title;
1922

20-
let _icon;
23+
const colors = getButtonColors(props, props.theme, props.bluebaseTheme);
2124

22-
if (loading) {
23-
_icon = (
24-
<ActivityIndicator color="#fff" style={{ marginRight: 8, width: 24, height: 24 }} />
25+
let _icon;
26+
27+
if (loading) {
28+
_icon = (
29+
<ActivityIndicator
30+
color={colors.text}
31+
style={{
32+
height: bluebaseTheme.spacing.unit * 3,
33+
marginRight: bluebaseTheme.spacing.unit,
34+
width: bluebaseTheme.spacing.unit * 3,
35+
}}
36+
/>
37+
);
38+
} else if (icon) {
39+
const size = icon.size || 24;
40+
41+
const iconProps = {
42+
color: colors.text,
43+
size,
44+
style: {
45+
lineHeight: size,
46+
marginRight: bluebaseTheme.spacing.unit,
47+
...icon.style,
48+
},
49+
...icon,
50+
};
51+
_icon = <DynamicIcon {...iconProps} />;
52+
}
53+
54+
return (
55+
<React.Fragment>
56+
{_icon}
57+
{content}
58+
</React.Fragment>
2559
);
26-
} else if (icon) {
27-
const size = icon.size || 24;
28-
29-
const iconProps = {
30-
size,
31-
style: {
32-
lineHeight: size,
33-
marginRight: 8,
34-
...icon.style,
35-
},
36-
...icon,
37-
};
38-
_icon = <DynamicIcon {...iconProps} />;
39-
}
40-
41-
return (
42-
<React.Fragment>
43-
{_icon}
44-
{content}
45-
</React.Fragment>
46-
);
47-
},
48-
49-
classes: 'classes',
50-
disabled: 'disbaled',
51-
fullWidth: 'fullWidth',
52-
onClick: 'onPress',
53-
size: 'size',
54-
style: ({ style }: any) => StyleSheet.flatten(style),
55-
variant: 'variant',
56-
})
60+
},
61+
62+
classes: 'classes',
63+
disabled: 'disabled',
64+
fullWidth: 'fullWidth',
65+
onClick: 'onPress',
66+
size: 'size',
67+
style: ({ style }: any) => StyleSheet.flatten(style),
68+
variant: 'variant',
69+
})
70+
)
5771
) as React.ComponentType<ButtonProps>;
5872

5973
Button.defaultProps = ButtonDefaultProps;

src/components/Button/__stories__/Button.stories.tsx

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -152,8 +152,11 @@ stories
152152
>
153153
Disabled
154154
</Button>
155-
<Button loading variant="contained" onPress={action('button-press')}>
156-
Link
155+
<Button loading variant="outlined" color="secondary" onPress={action('button-press')}>
156+
Outlined
157+
</Button>
158+
<Button loading variant="text" color="secondary" onPress={action('button-press')}>
159+
Text
157160
</Button>
158161
</React.Fragment>
159162
))
@@ -195,10 +198,19 @@ stories
195198
</Button>
196199
<Button
197200
icon={{ type: 'icon', name: 'favorite' }}
198-
variant="contained"
201+
color="secondary"
202+
variant="outlined"
203+
onPress={action('button-press')}
204+
>
205+
Outlined
206+
</Button>
207+
<Button
208+
icon={{ type: 'icon', name: 'favorite' }}
209+
variant="outlined"
199210
onPress={action('button-press')}
211+
disabled
200212
>
201-
Link
213+
Outlined & Disabled
202214
</Button>
203215
</React.Fragment>
204216
))

src/components/Button/styles.ts

Lines changed: 65 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,17 @@
11
import { ButtonProps } from '@bluebase/components';
22
import { Theme } from '@bluebase/core';
3-
import { Theme as MuiTheme } from '@material-ui/core';
3+
import { Theme as ThemeMui } from '@material-ui/core';
44
import { fade } from '@material-ui/core/styles/colorManipulator';
55

6-
export const styles = ({ color, disabled }: ButtonProps, muiTheme: MuiTheme, theme: Theme) => {
7-
if (!color || (color === 'default' && !disabled)) {
8-
return;
9-
}
10-
11-
const colors: {
12-
hover?: string;
13-
main?: string;
14-
text?: string;
15-
} = {};
6+
export const styles = (props: ButtonProps, muiTheme: ThemeMui, theme: Theme) => {
7+
const { color, disabled } = props;
8+
// debugger;
169

17-
if (disabled) {
10+
if (!color || (color === 'default' && !disabled) || disabled) {
1811
return;
1912
}
20-
// If color is NOT primary, secondary or default then create custom styles
21-
if (
22-
(color === 'primary' ||
23-
color === 'secondary' ||
24-
color === 'success' ||
25-
color === 'error' ||
26-
color === 'warning') &&
27-
!disabled
28-
) {
29-
colors.hover = (theme.palette as any)[color].dark;
30-
colors.main = (theme.palette as any)[color].main;
31-
colors.text = (theme.palette as any)[color].contrastText;
32-
} else {
33-
colors.hover = color;
34-
colors.main = color;
35-
colors.text = muiTheme.palette.getContrastText(color);
36-
}
13+
14+
const colors = getButtonColors(props, muiTheme, theme);
3715

3816
return {
3917
contained: {},
@@ -55,25 +33,77 @@ export const styles = ({ color, disabled }: ButtonProps, muiTheme: MuiTheme, the
5533
'@media (hover: none)': {
5634
backgroundColor: 'transparent',
5735
},
58-
backgroundColor: fade(colors.main as string, theme.palette.action.hoverOpacity),
59-
border: `1px solid ${colors.main as string}`,
36+
backgroundColor: fade(colors.text as string, theme.palette.action.hoverOpacity),
37+
border: `1px solid ${colors.text as string}`,
6038
// Reset on touch devices, it doesn't add specificity
6139
},
62-
border: `1px solid ${fade(colors.main as string, 0.5)}`,
63-
color: colors.main,
40+
border: `1px solid ${fade(colors.text as string, 0.5)}`,
41+
color: colors.text,
6442
},
6543
'&$text': {
6644
'&:hover': {
6745
'@media (hover: none)': {
6846
backgroundColor: 'transparent',
6947
},
70-
backgroundColor: fade(colors.main as string, theme.palette.action.hoverOpacity),
48+
backgroundColor: fade(colors.text as string, theme.palette.action.hoverOpacity),
7149
// Reset on touch devices, it doesn't add specificity
7250
},
73-
color: colors.main,
51+
color: colors.text,
7452
},
7553
},
7654
/* Styles applied to the root element if `variant="text"` */
7755
text: {},
7856
};
7957
};
58+
59+
export function getButtonColors(
60+
{ color, disabled, variant }: ButtonProps,
61+
muiTheme: ThemeMui,
62+
theme: Theme
63+
) {
64+
const colors: {
65+
hover?: string;
66+
main?: string;
67+
text?: string;
68+
} = {
69+
// hover: theme.palette.primary.main,
70+
// main: theme.palette.primary.main,
71+
// text: theme.palette.text.primary,
72+
};
73+
74+
if (disabled) {
75+
colors.hover = theme.palette.action.disabledBackground;
76+
colors.main = theme.palette.action.disabledBackground;
77+
colors.text = theme.palette.action.disabled;
78+
return colors;
79+
}
80+
81+
if (!color) {
82+
return colors;
83+
}
84+
85+
// If color is NOT primary, secondary or default then create custom styles
86+
if (
87+
color === 'primary' ||
88+
color === 'secondary' ||
89+
color === 'success' ||
90+
color === 'error' ||
91+
color === 'warning'
92+
) {
93+
if (variant === 'contained') {
94+
colors.hover = theme.palette[color].dark;
95+
colors.main = theme.palette[color].main;
96+
colors.text = theme.palette[color].contrastText;
97+
} else {
98+
// colors.hover = 'transparent';
99+
// colors.main = 'transparent';
100+
colors.text = theme.palette[color].main;
101+
}
102+
} else {
103+
colors.hover = color;
104+
colors.main = color;
105+
colors.text = muiTheme.palette.getContrastText(color);
106+
}
107+
108+
return colors;
109+
}

src/withPropsStyles.tsx

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,22 @@
11
import { Theme, withStyles } from '@material-ui/core/styles';
2+
23
import React from 'react';
34
import { ThemeConsumer } from '@bluebase/core';
45

56
const { createElement, forwardRef } = React;
67

78
// Docs: https://github.com/mui-org/material-ui/issues/7633#issuecomment-418211698
8-
export const withPropsStyles = ( style: any ) => {
9-
10-
const withPropsStylesInternal = ( component: React.ComponentType<any> ) => {
11-
12-
return forwardRef( (props, ref) => (
9+
export const withPropsStyles = (style: any) => {
10+
const withPropsStylesInternal = (component: React.ComponentType<any>) => {
11+
return forwardRef((props, ref) => (
1312
<ThemeConsumer>
14-
{({ theme: bluebaseTheme }) => {
15-
16-
const proxy = (theme: Theme) => style(props, theme, bluebaseTheme);
13+
{({ theme: bluebaseTheme }) => {
14+
const proxy = (theme: Theme) => style(props, theme, bluebaseTheme);
1715

18-
const hoc = withStyles(proxy)(component);
16+
const hoc = withStyles(proxy)(component);
1917

20-
return createElement(hoc, { ...props, ref }, props.children);
21-
}}
18+
return createElement(hoc, { ...props, ref, bluebaseTheme }, props.children);
19+
}}
2220
</ThemeConsumer>
2321
));
2422
};

0 commit comments

Comments
 (0)