Skip to content

Commit d7e66a4

Browse files
committed
Merge branch 'master' of github.com:salesforce-ux/design-system-react
2 parents 347db6b + 3bfb17b commit d7e66a4

File tree

6 files changed

+95
-25
lines changed

6 files changed

+95
-25
lines changed

components/SLDSButton/index.js

Lines changed: 64 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,35 +12,91 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
1212
import React from 'react';
1313
const classNames = require('classnames');
1414
import createChainedFunction from '../utils/create-chained-function';
15+
import {ButtonIcon, Icon} from '../SLDSIcons.js';
1516
import {omit} from 'lodash';
1617

1718
class Button extends React.Component {
1819

1920
constructor(props) {
2021
super(props);
21-
this.state = {};
22+
this.state = { active: false };
2223
};
2324

25+
componentWillMount(){
26+
/*===============================
27+
TODO: refactor so that React doesn't throw warnings in console
28+
for (var key in this.props) {
29+
if(this.props.hasOwnProperty(key) && typeof(this.props[key]) === 'string' && key !== 'label'){
30+
this.props[key] = this.props[key].toLowerCase();
31+
}
32+
}
33+
===============================*/
34+
}
35+
2436
onClick(e) {
2537
this.setState({ active: !this.state.active });
2638
}
2739

2840
getClassName() {
41+
let isStateful = this.props.stateful && this.state.active ? true : false;
2942
return classNames(this.props.className, 'slds-button', {
30-
[`slds-button--${this.props.flavor}`]: this.props.flavor,
31-
['slds-is-selected']: this.state.active,
43+
[`slds-button--${this.props.variant}`]: this.props.variant,
44+
['slds-is-selected']: isStateful,
3245
});
3346
}
3447

48+
renderIcon(){
49+
if(this.props.iconName){
50+
return (
51+
<ButtonIcon
52+
name={this.props.iconName}
53+
size={this.props.iconSize}
54+
position={this.props.iconPosition || 'left'} />
55+
);
56+
}
57+
}
58+
59+
3560
render() {
3661
const props = omit('className', this.props);
3762
const click = createChainedFunction(this.props.onClick, this.onClick.bind(this));
38-
return (
39-
<button className={this.getClassName()} {...props} onClick={click}>
40-
{this.props.children}
41-
</button>
42-
);
63+
64+
//If the button is only an icon render this:
65+
if(this.props.variant === 'icon'){
66+
return (
67+
<button className={this.getClassName()} {...props} onClick={click}>
68+
<Icon
69+
name={this.props.iconName}
70+
category='utility'
71+
size={this.props.iconSize}
72+
className={'slds-icon'} />
73+
<span className="slds-assistive-text">{this.props.label}</span>
74+
</button>
75+
);
76+
}
77+
//Else we assume the button has a visible label (with or without an icon):
78+
else{
79+
return (
80+
<button className={this.getClassName()} {...props} onClick={click}>
81+
82+
<span aria-live="assertive">{this.props.iconPosition === 'right' ? this.props.label : null}</span>
83+
84+
{this.renderIcon()}
85+
86+
<span aria-live="assertive">{(this.props.iconPosition === 'left' || !this.props.iconPosition) ? this.props.label : null}</span>
87+
88+
</button>
89+
);
90+
}
4391
}
4492
}
4593

94+
Button.propTypes = {
95+
label: React.PropTypes.string.isRequired,
96+
variant: React.PropTypes.oneOf(['base', 'neutral', 'brand', 'icon']),
97+
iconName: React.PropTypes.string,
98+
iconSize: React.PropTypes.oneOf(['x-small', 'small', 'medium', 'large']),
99+
iconPosition: React.PropTypes.oneOf(['left', 'right']),
100+
}
101+
46102
module.exports = Button;

components/SLDSIcons.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ export const ButtonIcon = React.createClass({
1818
getDefaultProps() {
1919

2020
return {
21-
category: 'utility',
21+
category: 'utility', // Utility Icon Reference: https://www.lightningdesignsystem.com/resources/icons#utility
2222
};
2323
},
2424

@@ -42,7 +42,7 @@ export const ButtonIcon = React.createClass({
4242
if (this.props.hint) {
4343
className = className + ' slds-button__icon--hint';
4444
}
45-
return <svg aria-hidden='true' className={className} dangerouslySetInnerHTML={{__html: useTag }} />;
45+
return <svg aria-hidden='true' className={className} dangerouslySetInnerHTML={{__html: useTag }} />;
4646
}
4747

4848
});

components/SLDSModal/index.jsx

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -113,10 +113,13 @@ module.exports = React.createClass( {
113113
>
114114
<div className='slds-modal__header'>
115115
<h2 className='slds-text-heading--medium'>{this.props.title}</h2>
116-
<SLDSButton className='slds-button slds-modal__close' onClick={this.closeModal}>
117-
<Icon name='close' category='utility' size='small'/>
118-
<span className='slds-assistive-text'>Close</span>
119-
</SLDSButton>
116+
<SLDSButton
117+
label='Close'
118+
variant='icon'
119+
iconName='close'
120+
iconSize='small'
121+
className='slds-modal__close'
122+
onClick={this.closeModal} />
120123
</div>
121124

122125
<div className='slds-modal__content'>

demo/code-snippets/SLDSButton.txt

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,9 @@
11

2-
<SLDSButton flavor="brand" onClick={this.handleButtonClick}>Test Button</SLDSButton>
2+
3+
<SLDSButton label='Test Button' variant='neutral' iconName='download' iconSize='small' iconPosition='left' onClick={this.handleButtonClick} />
4+
5+
* Only label is required
6+
* variant must be neutral, brand, or icon
7+
* iconSize must be small, medium, or large
8+
* iconPosition must be left or right
9+

demo/pages/HomePage/ButtonSection.jsx

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ module.exports = React.createClass( {
3737
render() {
3838
return (
3939

40-
4140
<div className='slds-p-around--medium'>
4241
<h3 className='slds-text-heading--medium slds-truncate'>
4342
Button
@@ -47,9 +46,13 @@ module.exports = React.createClass( {
4746
{require('raw-loader!../../code-snippets/SLDSButton.txt')}
4847
</PrismCode>
4948
<div className='slds-p-vertical--large'>
50-
<SLDSButton flavor='brand' onClick={this.handleButtonClick}>
51-
Test Button
52-
</SLDSButton>
49+
<SLDSButton
50+
label='Test Button'
51+
variant='neutral'
52+
iconName='download'
53+
iconSize='small'
54+
iconPosition='right'
55+
onClick={this.handleButtonClick} />
5356
</div>
5457
</div>
5558

demo/pages/HomePage/ModalSection.jsx

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -89,15 +89,16 @@ Utilize our detailed guidelines to confidently design excellent apps that fit ri
8989
*/}
9090

9191
<div className='slds-p-vertical--large'>
92-
<SLDSButton flavor='brand' onClick={this.openModal}>
93-
Open Modal
94-
</SLDSButton>
95-
<SLDSModal
92+
<SLDSButton
93+
label='Open Modal'
94+
variant='brand'
95+
onClick={this.openModal} />
96+
<SLDSModal
9697
isOpen={this.state.modalIsOpen}
9798
title={<span>Lightning Design System: Style with Ease</span>}
9899
footer={[
99-
<button className='slds-button slds-button--neutral' onClick={this.closeModal}>Cancel</button>,
100-
<button className='slds-button slds-button--neutral slds-button--brand' onClick={this.handleSubmitModal}>Save</button>
100+
<SLDSButton label='Cancel' variant='neutral' onClick={this.closeModal} />,
101+
<SLDSButton label='Save' variant='brand' onClick={this.handleSubmitModal} />
101102
]}
102103
onRequestClose={this.closeModal}>
103104
{this.getModalContent()}

0 commit comments

Comments
 (0)