@@ -6,8 +6,12 @@ import { Link } from 'react-router';
6
6
import { remSize , prop } from '../theme' ;
7
7
8
8
const kinds = {
9
+ primary : 'primary' ,
10
+ secondary : 'secondary'
11
+ } ;
12
+
13
+ const displays = {
9
14
block : 'block' ,
10
- icon : 'icon' ,
11
15
inline : 'inline'
12
16
} ;
13
17
@@ -23,45 +27,49 @@ const StyledButton = styled.button`
23
27
width: max-content;
24
28
text-decoration: none;
25
29
26
- color: ${ prop ( 'Button.default.foreground' ) } ;
27
- background-color: ${ prop ( 'Button.default.background' ) } ;
30
+ color: ${ ( { kind } ) => prop ( `Button.${ kind } .default.foreground` ) } ;
31
+ background-color: ${ ( { kind } ) =>
32
+ prop ( `Button.${ kind } .default.background` ) } ;
28
33
cursor: pointer;
29
- border: 2px solid ${ prop ( ' Button.default.border' ) } ;
34
+ border: 2px solid ${ ( { kind } ) => prop ( ` Button.${ kind } . default.border` ) } ;
30
35
border-radius: 2px;
31
36
padding: ${ remSize ( 8 ) } ${ remSize ( 25 ) } ;
32
37
line-height: 1;
33
38
34
39
svg * {
35
- fill: ${ prop ( ' Button.default.foreground' ) } ;
40
+ fill: ${ ( { kind } ) => prop ( ` Button.${ kind } . default.foreground` ) } ;
36
41
}
37
42
38
43
&:hover:not(:disabled) {
39
- color: ${ prop ( 'Button.hover.foreground' ) } ;
40
- background-color: ${ prop ( 'Button.hover.background' ) } ;
41
- border-color: ${ prop ( 'Button.hover.border' ) } ;
44
+ color: ${ ( { kind } ) => prop ( `Button.${ kind } .hover.foreground` ) } ;
45
+ background-color: ${ ( { kind } ) =>
46
+ prop ( `Button.${ kind } .hover.background` ) } ;
47
+ border-color: ${ ( { kind } ) => prop ( `Button.${ kind } .hover.border` ) } ;
42
48
43
49
svg * {
44
- fill: ${ prop ( ' Button.hover.foreground' ) } ;
50
+ fill: ${ ( { kind } ) => prop ( ` Button.${ kind } . hover.foreground` ) } ;
45
51
}
46
52
}
47
53
48
54
&:active:not(:disabled) {
49
- color: ${ prop ( 'Button.active.foreground' ) } ;
50
- background-color: ${ prop ( 'Button.active.background' ) } ;
55
+ color: ${ ( { kind } ) => prop ( `Button.${ kind } .active.foreground` ) } ;
56
+ background-color: ${ ( { kind } ) =>
57
+ prop ( `Button.${ kind } .active.background` ) } ;
51
58
52
59
svg * {
53
- fill: ${ prop ( ' Button.active.foreground' ) } ;
60
+ fill: ${ ( { kind } ) => prop ( ` Button.${ kind } . active.foreground` ) } ;
54
61
}
55
62
}
56
63
57
64
&:disabled {
58
- color: ${ prop ( 'Button.disabled.foreground' ) } ;
59
- background-color: ${ prop ( 'Button.disabled.background' ) } ;
60
- border-color: ${ prop ( 'Button.disabled.border' ) } ;
65
+ color: ${ ( { kind } ) => prop ( `Button.${ kind } .disabled.foreground` ) } ;
66
+ background-color: ${ ( { kind } ) =>
67
+ prop ( `Button.${ kind } .disabled.background` ) } ;
68
+ border-color: ${ ( { kind } ) => prop ( `Button.${ kind } .disabled.border` ) } ;
61
69
cursor: not-allowed;
62
70
63
71
svg * {
64
- fill: ${ prop ( ' Button.disabled.foreground' ) } ;
72
+ fill: ${ ( { kind } ) => prop ( ` Button.${ kind } . disabled.foreground` ) } ;
65
73
}
66
74
}
67
75
@@ -108,35 +116,38 @@ const StyledIconButton = styled.button`
108
116
height: ${ remSize ( 32 ) } px;
109
117
text-decoration: none;
110
118
111
- color: ${ prop ( ' Button.default.foreground' ) } ;
112
- background-color: ${ prop ( ' Button.hover.background' ) } ;
119
+ color: ${ ( { kind } ) => prop ( ` Button.${ kind } . default.foreground` ) } ;
120
+ background-color: ${ ( { kind } ) => prop ( ` Button.${ kind } . hover.background` ) } ;
113
121
cursor: pointer;
114
122
border: 1px solid transparent;
115
123
border-radius: 50%;
116
124
padding: ${ remSize ( 8 ) } ${ remSize ( 25 ) } ;
117
125
line-height: 1;
118
126
119
127
&:hover:not(:disabled) {
120
- color: ${ prop ( 'Button.hover.foreground' ) } ;
121
- background-color: ${ prop ( 'Button.hover.background' ) } ;
128
+ color: ${ ( { kind } ) => prop ( `Button.${ kind } .hover.foreground` ) } ;
129
+ background-color: ${ ( { kind } ) =>
130
+ prop ( `Button.${ kind } .hover.background` ) } ;
122
131
123
132
svg * {
124
- fill: ${ prop ( ' Button.hover.foreground' ) } ;
133
+ fill: ${ ( { kind } ) => prop ( ` Button.${ kind } . hover.foreground` ) } ;
125
134
}
126
135
}
127
136
128
137
&:active:not(:disabled) {
129
- color: ${ prop ( 'Button.active.foreground' ) } ;
130
- background-color: ${ prop ( 'Button.active.background' ) } ;
138
+ color: ${ ( { kind } ) => prop ( `Button.${ kind } .active.foreground` ) } ;
139
+ background-color: ${ ( { kind } ) =>
140
+ prop ( `Button.${ kind } .active.background` ) } ;
131
141
132
142
svg * {
133
- fill: ${ prop ( ' Button.active.foreground' ) } ;
143
+ fill: ${ ( { kind } ) => prop ( ` Button.${ kind } . active.foreground` ) } ;
134
144
}
135
145
}
136
146
137
147
&:disabled {
138
- color: ${ prop ( 'Button.disabled.foreground' ) } ;
139
- background-color: ${ prop ( 'Button.disabled.background' ) } ;
148
+ color: ${ ( { kind } ) => prop ( `Button.${ kind } .disabled.foreground` ) } ;
149
+ background-color: ${ ( { kind } ) =>
150
+ prop ( `Button.${ kind } .disabled.background` ) } ;
140
151
cursor: not-allowed;
141
152
}
142
153
@@ -151,10 +162,12 @@ const StyledIconButton = styled.button`
151
162
*/
152
163
const Button = ( {
153
164
children,
165
+ display,
154
166
href,
155
167
kind,
156
168
iconBefore,
157
169
iconAfter,
170
+ iconOnly,
158
171
'aria-label' : ariaLabel ,
159
172
to,
160
173
type,
@@ -170,16 +183,19 @@ const Button = ({
170
183
) ;
171
184
let StyledComponent = StyledButton ;
172
185
173
- if ( kind === kinds . inline ) {
186
+ if ( display === displays . inline ) {
174
187
StyledComponent = StyledInlineButton ;
175
- } else if ( kind === kinds . icon ) {
188
+ }
189
+
190
+ if ( iconOnly ) {
176
191
StyledComponent = StyledIconButton ;
177
192
}
178
193
179
194
if ( href ) {
180
195
return (
181
196
< StyledComponent
182
197
kind = { kind }
198
+ display = { display }
183
199
as = "a"
184
200
aria-label = { ariaLabel }
185
201
href = { href }
@@ -194,6 +210,7 @@ const Button = ({
194
210
return (
195
211
< StyledComponent
196
212
kind = { kind }
213
+ display = { display }
197
214
as = { Link }
198
215
aria-label = { ariaLabel }
199
216
to = { to }
@@ -205,7 +222,13 @@ const Button = ({
205
222
}
206
223
207
224
return (
208
- < StyledComponent kind = { kind } aria-label = { ariaLabel } type = { type } { ...props } >
225
+ < StyledComponent
226
+ kind = { kind }
227
+ display = { display }
228
+ aria-label = { ariaLabel }
229
+ type = { type }
230
+ { ...props }
231
+ >
209
232
{ content }
210
233
</ StyledComponent >
211
234
) ;
@@ -214,16 +237,19 @@ const Button = ({
214
237
Button . defaultProps = {
215
238
children : null ,
216
239
disabled : false ,
240
+ display : displays . block ,
217
241
iconAfter : null ,
218
242
iconBefore : null ,
219
- kind : kinds . block ,
243
+ iconOnly : false ,
244
+ kind : kinds . primary ,
220
245
href : null ,
221
246
'aria-label' : null ,
222
247
to : null ,
223
248
type : 'button'
224
249
} ;
225
250
226
251
Button . kinds = kinds ;
252
+ Button . displays = displays ;
227
253
228
254
Button . propTypes = {
229
255
/**
@@ -235,6 +261,10 @@ Button.propTypes = {
235
261
If the button can be activated or not
236
262
*/
237
263
disabled : PropTypes . bool ,
264
+ /**
265
+ * The display type of the button—inline or block
266
+ */
267
+ display : PropTypes . string ,
238
268
/**
239
269
* SVG icon to place after child content
240
270
*/
@@ -243,6 +273,10 @@ Button.propTypes = {
243
273
* SVG icon to place before child content
244
274
*/
245
275
iconBefore : PropTypes . element ,
276
+ /**
277
+ * If the button content is only an SVG icon
278
+ */
279
+ iconOnly : PropTypes . bool ,
246
280
/**
247
281
* The kind of button - determines how it appears visually
248
282
*/
0 commit comments