@@ -6,6 +6,12 @@ import { Link } from 'react-router';
66import { remSize , prop } from '../theme' ;
77import Icon , { ValidIconNameType } from './Icon' ;
88
9+ const kinds = {
10+ block : 'block' ,
11+ icon : 'icon' ,
12+ inline : 'inline' ,
13+ } ;
14+
915// The '&&&' will increase the specificity of the
1016// component's CSS so that it overrides the more
1117// general global styles
@@ -41,8 +47,74 @@ const StyledButton = styled.button`
4147 cursor: not-allowed;
4248 }
4349
44- > *:not(:last-child) {
45- margin-right: ${ remSize ( 8 ) } ;
50+ > * + * {
51+ margin-left: ${ remSize ( 8 ) } ;
52+ }
53+ }
54+ ` ;
55+
56+ const StyledInlineButton = styled . button `
57+ &&& {
58+ display: flex;
59+ justify-content: center;
60+ align-items: center;
61+
62+ text-decoration: none;
63+
64+ color: ${ prop ( 'primaryTextColor' ) } ;
65+ cursor: pointer;
66+ border: none;
67+ line-height: 1;
68+
69+ svg * {
70+ fill: ${ prop ( 'primaryTextColor' ) } ;
71+ }
72+
73+ &:disabled {
74+ cursor: not-allowed;
75+ }
76+
77+ > * + * {
78+ margin-left: ${ remSize ( 8 ) } ;
79+ }
80+ }
81+ ` ;
82+
83+ const StyledIconButton = styled . button `
84+ &&& {
85+ display: flex;
86+ justify-content: center;
87+ align-items: center;
88+
89+ width: ${ remSize ( 32 ) } px;
90+ height: ${ remSize ( 32 ) } px;
91+ text-decoration: none;
92+
93+ background-color: ${ prop ( 'buttonColorBackground' ) } ;
94+ color: ${ prop ( 'buttonColor' ) } ;
95+ cursor: pointer;
96+ border: 1px solid transparen;
97+ border-radius: 50%;
98+ padding: ${ remSize ( 8 ) } ${ remSize ( 25 ) } ;
99+ line-height: 1;
100+
101+ &:hover:not(:disabled) {
102+ color: ${ prop ( 'buttonHoverColor' ) } ;
103+ background-color: ${ prop ( 'buttonHoverColorBackground' ) } ;
104+
105+ svg * {
106+ fill: ${ prop ( 'buttonHoverColor' ) } ;
107+ }
108+ }
109+
110+ &:disabled {
111+ color: ${ prop ( 'buttonDisabledColor' ) } ;
112+ background-color: ${ prop ( 'buttonDisabledColorBackground' ) } ;
113+ cursor: not-allowed;
114+ }
115+
116+ > * + * {
117+ margin-left: ${ remSize ( 8 ) } ;
46118 }
47119 }
48120` ;
@@ -51,42 +123,54 @@ const StyledButton = styled.button`
51123 * A Button performs an primary action
52124 */
53125const Button = ( {
54- children, href, iconAfterName, iconBeforeName, label, to, type, ...props
126+ children, href, iconAfterName, iconBeforeName, kind , label, to, type, ...props
55127} ) => {
56128 const iconAfter = iconAfterName && < Icon name = { iconAfterName } /> ;
57129 const iconBefore = iconBeforeName && < Icon name = { iconBeforeName } /> ;
130+ const hasChildren = React . Children . count ( children ) > 0 ;
131+
132+ const content = < > { iconBefore } { hasChildren && < span > { children } </ span > } { iconAfter } </ > ;
58133
59- const content = < > { iconBefore } < span > { children } </ span > { iconAfter } </ > ;
134+ let StyledComponent = StyledButton ;
135+
136+ if ( kind === kinds . inline ) {
137+ StyledComponent = StyledInlineButton ;
138+ } else if ( kind === kinds . icon ) {
139+ StyledComponent = StyledIconButton ;
140+ }
60141
61142 if ( href ) {
62- return < StyledButton as = "a" aria-label = { label } href = { href } { ...props } > { content } </ StyledButton > ;
143+ return < StyledComponent kind = { kind } as = "a" aria-label = { label } href = { href } { ...props } > { content } </ StyledComponent > ;
63144 }
64145
65146 if ( to ) {
66- return < StyledButton as = { Link } aria-label = { label } to = { to } { ...props } > { content } </ StyledButton > ;
147+ return < StyledComponent kind = { kind } as = { Link } aria-label = { label } to = { to } { ...props } > { content } </ StyledComponent > ;
67148 }
68149
69- return < StyledButton aria-label = { label } type = { type } { ...props } > { content } </ StyledButton > ;
150+ return < StyledComponent kind = { kind } aria-label = { label } type = { type } { ...props } > { content } </ StyledComponent > ;
70151} ;
71152
72153Button . defaultProps = {
154+ children : null ,
73155 disabled : false ,
74156 iconAfterName : null ,
75157 iconBeforeName : null ,
158+ kind : kinds . block ,
76159 href : null ,
77160 label : null ,
78161 to : null ,
79162 type : 'button' ,
80163} ;
81164
82165Button . iconNames = Icon . names ;
166+ Button . kinds = kinds ;
83167
84168Button . propTypes = {
85169 /**
86170 * The visible part of the button, telling the user what
87171 * the action is
88172 */
89- children : PropTypes . element . isRequired ,
173+ children : PropTypes . element ,
90174 /**
91175 If the button can be activated or not
92176 */
@@ -95,11 +179,14 @@ Button.propTypes = {
95179 * Name of icon to place before child content
96180 */
97181 iconAfterName : ValidIconNameType ,
98-
99182 /**
100183 * Name of icon to place after child content
101184 */
102185 iconBeforeName : ValidIconNameType ,
186+ /**
187+ * The kind of button - determines how it appears visually
188+ */
189+ kind : PropTypes . oneOf ( Object . values ( kinds ) ) ,
103190 /**
104191 * Specifying an href will use an <a> to link to the URL
105192 */
0 commit comments