Skip to content

Commit d652580

Browse files
authored
Merge pull request #39 from arturbien/new-components
Flat variants for components
2 parents b5aa123 + bdb6915 commit d652580

File tree

24 files changed

+724
-256
lines changed

24 files changed

+724
-256
lines changed

src/components/Bar/Bar.stories.js

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,8 @@ storiesOf("Bar", module)
2121
<AppBar>
2222
<Toolbar>
2323
<Bar />
24-
<Button flat accent>
25-
Edit
26-
</Button>
27-
<Button flat accent disabled>
24+
<Button variant="menu">Edit</Button>
25+
<Button variant="menu" disabled>
2826
Save
2927
</Button>
3028
<Bar />

src/components/Button/Button.js

Lines changed: 45 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,61 @@
11
import React from "react";
22
import propTypes from "prop-types";
33

4-
import styled from "styled-components";
4+
import styled, { css } from "styled-components";
55
import {
66
createBorderStyles,
7+
createWellBorderStyles,
78
createBoxStyles,
9+
createFlatBoxStyles,
810
createDisabledTextStyles
911
} from "../common";
1012
import { blockSizes, fontSizes, padding } from "../common/system";
1113

12-
const StyledButton = styled.button`
13-
${createBoxStyles()};
14+
const commonButtonStyles = css`
1415
position: relative;
1516
display: inline-flex;
1617
align-items: center;
1718
justify-content: center;
18-
${props =>
19-
props.flat
20-
? null
21-
: props.active
22-
? createBorderStyles(true)
23-
: createBorderStyles(false)}
24-
height: ${props => blockSizes[props.size]};
25-
width: ${props =>
26-
props.fullWidth ? "100%" : props.square ? blockSizes[props.size] : "auto"};
27-
padding: ${props => (props.square ? 0 : "0 " + padding.sm)};
19+
height: ${({ size }) => blockSizes[size]};
20+
width: ${({ fullWidth, square, size }) =>
21+
fullWidth ? "100%" : square ? blockSizes[size] : "auto"};
22+
padding: ${({ square }) => (square ? 0 : "0 " + padding.sm)};
2823
font-size: ${fontSizes.md};
29-
30-
${props => props.isDisabled && createDisabledTextStyles()}
3124
&:active {
32-
${props => !props.isDisabled && !props.flat && createBorderStyles(true)}
33-
34-
padding-top: ${props => !props.isDisabled && "2px"};
35-
25+
padding-top: ${({ isDisabled }) => !isDisabled && "2px"};
3626
}
37-
padding-top: ${props => props.active && !props.isDisabled && "2px"};
38-
${props => props.flat && "border: none;"}
27+
padding-top: ${({ active, isDisabled }) => active && !isDisabled && "2px"};
28+
`;
29+
30+
const StyledButton = styled.button`
31+
${({ variant }) =>
32+
variant === "flat"
33+
? css`
34+
${createFlatBoxStyles()} /* background: none; */
35+
`
36+
: variant === "menu"
37+
? css`
38+
${createBoxStyles()};
39+
border: 2px solid transparent;
40+
&:hover {
41+
${({ isDisabled }) => !isDisabled && createWellBorderStyles(false)}
42+
}
43+
&:active {
44+
${({ isDisabled }) => !isDisabled && createWellBorderStyles(true)}
45+
}
46+
${({ active }) => active && createBorderStyles(true)}
47+
${({ isDisabled }) => isDisabled && createDisabledTextStyles()}
48+
`
49+
: css`
50+
${createBoxStyles()};
51+
${({ active }) =>
52+
active ? createBorderStyles(true) : createBorderStyles(false)}
53+
&:active {
54+
${({ isDisabled }) => !isDisabled && createBorderStyles(true)}
55+
}
56+
${({ isDisabled }) => isDisabled && createDisabledTextStyles()}
57+
`}
58+
${commonButtonStyles}
3959
`;
4060

4161
const Button = ({
@@ -47,22 +67,22 @@ const Button = ({
4767
size,
4868
square,
4969
active,
50-
flat,
70+
variant,
5171
className,
5272
children,
5373
...otherProps
5474
}) => {
5575
return (
5676
<StyledButton
5777
type={type}
78+
variant={variant}
5879
onClick={disabled ? undefined : onClick}
5980
style={style}
6081
isDisabled={disabled}
6182
fullWidth={fullWidth}
6283
size={size}
6384
square={square}
6485
active={active}
65-
flat={flat}
6686
className={className}
6787
style={style}
6888
// onTouchStart below to enable button :active style on iOS
@@ -83,7 +103,7 @@ Button.defaultProps = {
83103
size: "md",
84104
square: false,
85105
active: false,
86-
flat: false
106+
variant: "default"
87107
};
88108

89109
Button.propTypes = {
@@ -95,7 +115,7 @@ Button.propTypes = {
95115
size: propTypes.oneOf(["sm", "md", "lg"]),
96116
square: propTypes.bool,
97117
active: propTypes.bool,
98-
flat: propTypes.bool,
118+
variant: propTypes.oneOf(["default", "menu", "flat"]),
99119
className: propTypes.string,
100120
children: propTypes.node.isRequired
101121
};

src/components/Button/Button.stories.js

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,15 @@ import { withInfo } from "@storybook/addon-info";
33
import { storiesOf } from "@storybook/react";
44
import { action } from "@storybook/addon-actions";
55

6-
import styled from "styled-components";
6+
import styled, {ThemeProvider} from "styled-components";
77

8-
import Button from "./Button";
8+
import { Button, Window, WindowContent, Cutout, Toolbar } from "../";
99
export const actions = { onClick: action("onClick") };
1010

11+
const StyledCutout = styled(Cutout)`
12+
background: ${({theme})=>theme.canvas};
13+
`;
14+
1115
storiesOf("Button", module)
1216
.addDecorator(story => (
1317
<div
@@ -45,8 +49,36 @@ storiesOf("Button", module)
4549
💖
4650
</Button>
4751
))
48-
.add("flat", () => (
49-
<Button {...actions} flat size="sm" accent>
52+
.add("menu button", () => (
53+
<Button {...actions} variant="menu" size="sm" accent>
5054
File
5155
</Button>
56+
))
57+
.add("flat button", () => (
58+
<Window>
59+
<WindowContent>
60+
<StyledCutout
61+
style={{ padding: "1rem", width: "300px" }}
62+
>
63+
<p style={{ lineHeight: 1.3 }}>
64+
When you want to use Buttons on a light background (like scrollable
65+
content), just use the flat variant:
66+
</p>
67+
<div
68+
style={{
69+
marginTop: "1.5rem"
70+
}}
71+
>
72+
<Toolbar>
73+
<Button {...actions} variant="flat" fullWidth accent>
74+
OK
75+
</Button>
76+
<Button {...actions} variant="flat" disabled fullWidth accent>
77+
Cancel
78+
</Button>
79+
</Toolbar>
80+
</div>
81+
</StyledCutout>
82+
</WindowContent>
83+
</Window>
5284
));

src/components/Checkbox/Checkbox.js

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ import React, { useState } from "react";
22
import propTypes from "prop-types";
33

44
import styled, { css } from "styled-components";
5-
import { createDisabledTextStyles } from "../common";
5+
import { createDisabledTextStyles, createFlatBoxStyles } from "../common";
6+
67
import { padding, fontSizes } from "../common/system";
78
import Cutout from "../Cutout/Cutout";
89

@@ -44,27 +45,37 @@ const createCheckmarkSymbol = ({ checked }) =>
4445
transform: translate(-50%, -50%) rotate(45deg);
4546
}
4647
`;
47-
const StyledCheckmark = styled(Cutout)`
48+
const sharedCheckmarkStyles = css`
4849
position: absolute;
4950
top: 50%;
5051
left: 0;
5152
transform: translateY(-50%);
5253
width: 20px;
5354
height: 20px;
55+
${props => createCheckmarkSymbol(props)}
56+
`;
57+
const StyledCheckmark = styled(Cutout)`
58+
${sharedCheckmarkStyles}
5459
background: ${({ theme, isDisabled }) =>
5560
isDisabled ? theme.material : theme.canvas};
56-
${props => createCheckmarkSymbol(props)};
5761
box-shadow: ${({ shadow }) =>
5862
shadow ? `inset 3px 3px 10px rgba(0, 0, 0, 0.1)` : "none"};
5963
&:before {
6064
box-shadow: none;
6165
}
6266
`;
63-
67+
const StyledFlatCheckmark = styled.div`
68+
${createFlatBoxStyles()}
69+
${sharedCheckmarkStyles}
70+
background: ${({ theme, isDisabled }) =>
71+
isDisabled ? theme.flatLight : theme.canvas};
72+
73+
`;
6474
const Checkbox = ({
6575
onChange,
6676
label,
6777
disabled,
78+
variant,
6879
value,
6980
checked,
7081
defaultChecked,
@@ -74,8 +85,9 @@ const Checkbox = ({
7485
shadow,
7586
...otherProps
7687
}) => {
77-
let Input, isChecked;
88+
let Input;
7889

90+
const Checkmark = variant === "flat" ? StyledFlatCheckmark : StyledCheckmark;
7991
if (defaultChecked || checked === undefined) {
8092
const [state, setState] = useState(defaultChecked || false);
8193

@@ -95,11 +107,7 @@ const Checkbox = ({
95107
name={name}
96108
{...otherProps}
97109
/>
98-
<StyledCheckmark
99-
checked={state}
100-
isDisabled={disabled}
101-
shadow={shadow}
102-
/>
110+
<Checkmark checked={state} isDisabled={disabled} shadow={shadow} />
103111
</>
104112
);
105113
} else {
@@ -114,11 +122,7 @@ const Checkbox = ({
114122
name={name}
115123
{...otherProps}
116124
/>
117-
<StyledCheckmark
118-
checked={checked}
119-
isDisabled={disabled}
120-
shadow={shadow}
121-
/>
125+
<Checkmark checked={checked} isDisabled={disabled} shadow={shadow} />
122126
</>
123127
);
124128
}
@@ -135,6 +139,7 @@ Checkbox.defaultProps = {
135139
value: null,
136140
label: "",
137141
disabled: false,
142+
variant: "default",
138143
shadow: true
139144
};
140145

@@ -149,6 +154,7 @@ Checkbox.propTypes = {
149154
label: propTypes.oneOfType([propTypes.string, propTypes.number]),
150155
checked: propTypes.bool,
151156
disabled: propTypes.bool,
157+
variant: propTypes.oneOf(["default", "flat"]),
152158
shadow: propTypes.bool,
153159
style: propTypes.object
154160
};

src/components/Checkbox/Checkbox.stories.js

Lines changed: 34 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,48 @@
11
import React from "react";
22
import { storiesOf } from "@storybook/react";
3+
import styled from "styled-components";
34

4-
import Checkbox from "./Checkbox";
5-
import { Fieldset, Toolbar, Button } from "../";
5+
import { Checkbox, Fieldset, Toolbar, Button, Cutout } from "../";
6+
7+
const StyledCutout = styled(Cutout)`
8+
background: ${({ theme }) => theme.canvas};
9+
`;
10+
const Wrapper = styled.div`
11+
background: ${({ theme }) => theme.material};
12+
padding: 5rem;
13+
`;
614
storiesOf("Checkbox", module)
7-
.addDecorator(story => (
8-
<div
9-
style={{
10-
padding: "5rem",
11-
background: "#ced0cf"
12-
}}
13-
>
14-
{story()}
15-
</div>
16-
))
15+
.addDecorator(story => <Wrapper>{story()}</Wrapper>)
1716
.add("controlled group", () => <ControlledCheckboxGroupExample />)
1817
.add("uncontrolled", () => (
1918
<Checkbox
2019
defaultChecked={true}
2120
value="single"
2221
label="I'm single 😥 ...and no one's controlling me 😎"
2322
/>
23+
))
24+
.add("flat", () => (
25+
<StyledCutout style={{ padding: "1rem", width: "300px" }}>
26+
<p style={{ lineHeight: 1.3 }}>
27+
When you want to add input field on a light background (like scrollable
28+
content), just use the flat variant:
29+
</p>
30+
<div style={{ marginTop: "1rem" }}>
31+
<Checkbox
32+
variant="flat"
33+
defaultChecked={true}
34+
value="single"
35+
label="Earth is flat 🌍"
36+
/>
37+
<Checkbox
38+
variant="flat"
39+
defaultChecked={false}
40+
value="single"
41+
label="Reptilians rule the world 🦎"
42+
disabled
43+
/>
44+
</div>
45+
</StyledCutout>
2446
));
2547

2648
class ControlledCheckboxGroupExample extends React.Component {

0 commit comments

Comments
 (0)