Skip to content

Commit 0e67fa3

Browse files
donniebergtweettypography
authored andcommitted
Add Spinner component, react-story, and test. (#340)
* Add Spinner component, react-story, and test. * Add a bit more to the release notes
1 parent d7d8eba commit 0e67fa3

File tree

9 files changed

+192
-3
lines changed

9 files changed

+192
-3
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ npm run dist
3333

3434
## Getting Started
3535

36-
Note: `design-system-react` is optimized for React 0.14.x and uses Lightning Design System 1.0.3.
36+
Note: `design-system-react` is optimized for React 0.14.x and uses Lightning Design System 2.1.0-beta.3.
3737

3838
### NPM
3939

@@ -85,7 +85,7 @@ Note: the SLDSPopoverTooltip requires a focusable element as a child (ie. either
8585

8686
4. **Which version of React and Lightning Design System do you support?**
8787

88-
Design System React is optimized for React 0.14.x and uses Lightning Design System 1.0.3.
88+
Design System React is optimized for React 0.14.x and uses Lightning Design System 2.1.0-beta.3.
8989

9090
5. **Which browsers are supported?**
9191

RELEASENOTES.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,18 @@
22
# React Components: design-system-react
33
# Release notes
44

5+
## Release 0.0.31
6+
7+
**MAJOR CHANGES**
8+
- Added new Spinner component
9+
- Updated the ContextBar component
10+
- Added a highlighting utility
11+
- Added a custom cell type to DataTable using the highlighter
12+
13+
**OTHER**
14+
- Remove isRequired for iconCategory in ButtonGroup
15+
- Additional bug fixes and code cleanup
16+
517
## Release 0.0.29
618

719
**MAJOR CHANGES**

components/index.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,9 @@ export PageHeader from './page-header';
9898
export SLDSPopoverTooltip from './popover-tooltip';
9999
export PopoverTooltip from './popover-tooltip';
100100

101+
export SLDSSpinner from './spinner';
102+
export Spinner from './spinner';
103+
101104
export SLDSTimepicker from './time-picker';
102105
export Timepicker from './time-picker';
103106

components/spinner/index.jsx

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/*
2+
Copyright (c) 2015, salesforce.com, inc. All rights reserved.
3+
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
4+
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
5+
Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
6+
Neither the name of salesforce.com, inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
7+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
8+
*/
9+
10+
// # Spinner Component --- SLDS for React
11+
12+
// Implements the [Spinner design pattern - 2.1.0-beta.3 (204)](https://latest-204.lightningdesignsystem.com/components/spinners) in React.
13+
14+
// ### React
15+
// React is an external dependency of the project.
16+
import React from 'react';
17+
18+
import classNames from 'classnames';
19+
20+
// ## Constants
21+
import { SPINNER } from '../../utilities/constants';
22+
23+
// Removes the need for `PropTypes`.
24+
const { PropTypes } = React;
25+
26+
// ### Prop Types
27+
const PROP_TYPES = {
28+
/**
29+
* Determines the size of the spinner
30+
*/
31+
size: PropTypes.oneOf(['small', 'medium', 'large']),
32+
/**
33+
* Determines the color of the spinner: `base` is gray, `brand` is blue, and `inverse` is white.
34+
*/
35+
variant: PropTypes.oneOf(['base', 'brand', 'inverse'])
36+
};
37+
38+
const DEFAULT_PROPS = {
39+
size: 'medium',
40+
variant: 'base'
41+
};
42+
43+
// ## Spinner
44+
const Spinner = (props) => {
45+
const {
46+
variant,
47+
size
48+
} = props;
49+
50+
const sizeClass = `slds-spinner--${props.size}`;
51+
const variants = {
52+
brand: 'slds-spinner--brand',
53+
inverse: 'slds-spinner--inverse'
54+
};
55+
56+
return (
57+
<div className='slds-spinner_container'>
58+
<div
59+
className={classNames('slds-spinner', sizeClass, variants[props.variant])}
60+
aria-hidden='false'
61+
role='alert'
62+
>
63+
<div className='slds-spinner__dot-a'></div>
64+
<div className='slds-spinner__dot-b'></div>
65+
</div>
66+
</div>
67+
);
68+
};
69+
70+
Spinner.displayName = SPINNER;
71+
Spinner.propTypes = PROP_TYPES;
72+
Spinner.defaultProps = DEFAULT_PROPS;
73+
74+
module.exports = Spinner;
75+

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "design-system-react",
3-
"version": "0.0.30",
3+
"version": "0.0.31",
44
"description": "Salesforce Lightning Design System React components",
55
"license": "BSD-3-Clause",
66
"scripts": {

stories/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,4 @@ export default from './context-bar';
77
export default from './data-table';
88
export default from './icon';
99
export default from './input';
10+
export default from './spinner';

stories/spinner/index.jsx

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/* eslint-disable indent */
2+
3+
import React from 'react';
4+
import { storiesOf, action } from '@kadira/storybook';
5+
6+
import { SPINNER } from '../../utilities/constants';
7+
import Spinner from '../../components/spinner';
8+
9+
const getSpinner = props => (
10+
<Spinner {...props} />
11+
);
12+
13+
const inverseContainer = {
14+
backgroundColor: '#4bca81',
15+
position: 'absolute',
16+
width: '100%',
17+
height: '100%'
18+
};
19+
20+
storiesOf(SPINNER, module)
21+
.addDecorator(getStory => <div className="slds-p-around--medium">{getStory()}</div>)
22+
.add('Small', () => getSpinner({ size: 'small', variant: 'base' }))
23+
.add('Medium', () => getSpinner({ size: 'medium', variant: 'base' }))
24+
.add('Large', () => getSpinner({ size: 'large', variant: 'base' }))
25+
.add('Brand Small', () => getSpinner({ size: 'small', variant: 'brand' }))
26+
.add('Brand Medium', () => getSpinner({ size: 'medium', variant: 'brand' }))
27+
.add('Brand Large', () => getSpinner({ size: 'large', variant: 'brand' }))
28+
29+
.addDecorator(getStory => <div className="slds-p-around--medium" style={inverseContainer}>{getStory()}</div>)
30+
.add('Inverse Small', () => getSpinner({ size: 'small', variant: 'inverse' }))
31+
.add('Inverse Medium', () => getSpinner({ size: 'medium', variant: 'inverse' }))
32+
.add('Inverse Large', () => getSpinner({ size: 'large', variant: 'inverse' }))

tests/spinner/spinner.test.jsx

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/* eslint-disable indent */
2+
3+
import React from 'react';
4+
import ReactDOM from 'react-dom';
5+
import assign from 'lodash.assign';
6+
import chai from 'chai';
7+
8+
import {Spinner} from '../../components';
9+
10+
chai.should();
11+
12+
describe('Spinner: ', function () {
13+
// Setup and takedown
14+
const renderSpinner = (instance) => {
15+
return function () {
16+
this.dom = document.createElement('div');
17+
document.body.appendChild(this.dom);
18+
this.component = ReactDOM.render(instance, this.dom);
19+
};
20+
};
21+
22+
function removeSpinner () {
23+
ReactDOM.unmountComponentAtNode(this.dom);
24+
document.body.removeChild(this.dom);
25+
};
26+
27+
const getSpinner = dom => dom.querySelector('.slds-spinner');
28+
29+
// Tests
30+
describe('Default spinner renders properly', () => {
31+
before(renderSpinner(
32+
<Spinner />
33+
));
34+
35+
after(removeSpinner);
36+
37+
it('Spinner exists', function () {
38+
const spinner = getSpinner(this.dom);
39+
spinner.should.not.be.undefined;
40+
});
41+
42+
it('renders default classes when no props passed in', function () {
43+
const spinner = getSpinner(this.dom);
44+
spinner.className.should.equal('slds-spinner slds-spinner--medium');
45+
});
46+
})
47+
48+
describe('Props render proper css classes', function () {
49+
50+
beforeEach(renderSpinner(
51+
<Spinner size='small' variant='brand' />
52+
));
53+
54+
afterEach(removeSpinner);
55+
56+
it('renders correct classes when props passed in', function () {
57+
const spinner = getSpinner(this.dom);
58+
spinner.className.should.include('slds-spinner--small slds-spinner--brand');
59+
});
60+
61+
});
62+
63+
});
64+
65+

utilities/constants.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,4 @@ export const ICON_INPUT = 'SLDSIconInput';
3232
export const LOOKUP = 'SLDSLookup';
3333
export const MEDIA_OBJECT = 'SLDSMediaObject';
3434
export const MENU_DROPDOWN = 'SLDSMenuDropdown';
35+
export const SPINNER = 'SLDSSPINNER';

0 commit comments

Comments
 (0)