Skip to content

Commit e1c95b3

Browse files
author
Trevor Robinson
committedApr 17, 2015
[changed] Renamed constants to styleMaps and added styleMaps.addStyle()
1 parent 527e21f commit e1c95b3

8 files changed

+79
-18
lines changed
 

Diff for: ‎src/BootstrapMixin.js

+9-9
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,28 @@
1-
import React from 'react';
2-
import constants from './constants';
1+
import styleMaps from './styleMaps';
2+
import CustomPropTypes from './utils/CustomPropTypes';
33

44
const BootstrapMixin = {
55
propTypes: {
6-
bsClass: React.PropTypes.oneOf(Object.keys(constants.CLASSES)),
7-
bsStyle: React.PropTypes.oneOf(Object.keys(constants.STYLES)),
8-
bsSize: React.PropTypes.oneOf(Object.keys(constants.SIZES))
6+
bsClass: CustomPropTypes.keyOf(styleMaps.CLASSES),
7+
bsStyle: CustomPropTypes.keyOf(styleMaps.STYLES),
8+
bsSize: CustomPropTypes.keyOf(styleMaps.SIZES)
99
},
1010

1111
getBsClassSet() {
1212
let classes = {};
1313

14-
let bsClass = this.props.bsClass && constants.CLASSES[this.props.bsClass];
14+
let bsClass = this.props.bsClass && styleMaps.CLASSES[this.props.bsClass];
1515
if (bsClass) {
1616
classes[bsClass] = true;
1717

1818
let prefix = bsClass + '-';
1919

20-
let bsSize = this.props.bsSize && constants.SIZES[this.props.bsSize];
20+
let bsSize = this.props.bsSize && styleMaps.SIZES[this.props.bsSize];
2121
if (bsSize) {
2222
classes[prefix + bsSize] = true;
2323
}
2424

25-
let bsStyle = this.props.bsStyle && constants.STYLES[this.props.bsStyle];
25+
let bsStyle = this.props.bsStyle && styleMaps.STYLES[this.props.bsStyle];
2626
if (this.props.bsStyle) {
2727
classes[prefix + bsStyle] = true;
2828
}
@@ -32,7 +32,7 @@ const BootstrapMixin = {
3232
},
3333

3434
prefixClass(subClass) {
35-
return constants.CLASSES[this.props.bsClass] + '-' + subClass;
35+
return styleMaps.CLASSES[this.props.bsClass] + '-' + subClass;
3636
}
3737
};
3838

Diff for: ‎src/Col.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import React from 'react';
22
import classNames from 'classnames';
3-
import constants from './constants';
3+
import styleMaps from './styleMaps';
44

55
const Col = React.createClass({
66
propTypes: {
@@ -33,8 +33,8 @@ const Col = React.createClass({
3333
let ComponentClass = this.props.componentClass;
3434
let classes = {};
3535

36-
Object.keys(constants.SIZES).forEach(function (key) {
37-
let size = constants.SIZES[key];
36+
Object.keys(styleMaps.SIZES).forEach(function (key) {
37+
let size = styleMaps.SIZES[key];
3838
let prop = size;
3939
let classPart = size + '-';
4040

Diff for: ‎src/Glyphicon.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
import React from 'react';
22
import classNames from 'classnames';
33
import BootstrapMixin from './BootstrapMixin';
4-
import constants from './constants';
4+
import styleMaps from './styleMaps';
55

66
const Glyphicon = React.createClass({
77
mixins: [BootstrapMixin],
88

99
propTypes: {
10-
glyph: React.PropTypes.oneOf(constants.GLYPHS).isRequired
10+
glyph: React.PropTypes.oneOf(styleMaps.GLYPHS).isRequired
1111
},
1212

1313
getDefaultProps() {

Diff for: ‎src/index.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ import Table from './Table';
4747
import TabPane from './TabPane';
4848
import Tooltip from './Tooltip';
4949
import Well from './Well';
50-
import constants from './constants';
50+
import styleMaps from './styleMaps';
5151

5252
export default {
5353
Accordion,
@@ -99,5 +99,5 @@ export default {
9999
TabPane,
100100
Tooltip,
101101
Well,
102-
constants
102+
styleMaps
103103
};

Diff for: ‎src/constants.js renamed to ‎src/styleMaps.js

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
export default {
1+
const styleMaps = {
22
CLASSES: {
33
'alert': 'alert',
44
'button': 'btn',
@@ -31,6 +31,9 @@ export default {
3131
'tabs': 'tabs',
3232
'pills': 'pills'
3333
},
34+
addStyle: function(name) {
35+
styleMaps.STYLES[name] = name;
36+
},
3437
SIZES: {
3538
'large': 'lg',
3639
'medium': 'md',
@@ -299,3 +302,5 @@ export default {
299302
'menu-up'
300303
]
301304
};
305+
306+
export default styleMaps;

Diff for: ‎src/utils/CustomPropTypes.js

+24-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,16 @@ let CustomPropTypes = {
1313
* @param componentName
1414
* @returns {Error|undefined}
1515
*/
16-
mountable: createMountableChecker()
16+
mountable: createMountableChecker(),
17+
/**
18+
* Checks whether a prop matches a key of an associated object
19+
*
20+
* @param props
21+
* @param propName
22+
* @param componentName
23+
* @returns {Error|undefined}
24+
*/
25+
keyOf: createKeyOfChecker
1726
};
1827

1928
/**
@@ -57,4 +66,18 @@ function createMountableChecker() {
5766
return createChainableTypeChecker(validate);
5867
}
5968

69+
function createKeyOfChecker(obj) {
70+
function validate(props, propName, componentName) {
71+
let propValue = props[propName];
72+
if (!obj.hasOwnProperty(propValue)) {
73+
let valuesString = JSON.stringify(Object.keys(obj));
74+
return new Error(
75+
`Invalid prop '${propName}' of value '${propValue}' ` +
76+
`supplied to '${componentName}', expected one of ${valuesString}.`
77+
);
78+
}
79+
}
80+
return createChainableTypeChecker(validate);
81+
}
82+
6083
export default CustomPropTypes;

Diff for: ‎test/BootstrapMixinSpec.js

+11
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import React from 'react';
22
import ReactTestUtils from 'react/lib/ReactTestUtils';
33
import BootstrapMixin from '../src/BootstrapMixin';
4+
import styleMaps from '../src/styleMaps';
45

56
let Component;
67

@@ -195,5 +196,15 @@ describe('BootstrapMixin', function () {
195196
);
196197
assert.equal(instance.prefixClass('title'), 'btn-title');
197198
});
199+
200+
it('should return "btn btn-wacky"', function () {
201+
styleMaps.addStyle('wacky');
202+
let instance = ReactTestUtils.renderIntoDocument(
203+
<Component bsClass='button' bsStyle='wacky'>
204+
content
205+
</Component>
206+
);
207+
assert.deepEqual(instance.getBsClassSet(), {'btn': true, 'btn-wacky': true});
208+
});
198209
});
199210
});

Diff for: ‎test/CustomPropTypesSpec.js

+22
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,26 @@ describe('CustomPropTypes', function () {
2525
assert.isUndefined(validate(ReactTestUtils.renderIntoDocument(<div />)));
2626
});
2727
});
28+
29+
describe('keyOf', function () {
30+
let obj = {'foo': 1};
31+
function validate(prop) {
32+
return CustomPropTypes.keyOf(obj)({p: prop}, 'p', 'Component');
33+
}
34+
function validateRequired(prop) {
35+
return CustomPropTypes.keyOf(obj).isRequired({p: prop}, 'p', 'Component');
36+
}
37+
38+
it('Should return error with non-key values', function() {
39+
assert.instanceOf(validateRequired(), Error);
40+
assert.instanceOf(validateRequired(null), Error);
41+
assert.instanceOf(validate('bar'), Error);
42+
});
43+
it('Should return undefined with key values', function() {
44+
assert.isUndefined(validate());
45+
assert.isUndefined(validate('foo'));
46+
obj.bar = 2;
47+
assert.isUndefined(validate('bar'));
48+
});
49+
});
2850
});

0 commit comments

Comments
 (0)
Please sign in to comment.