Skip to content

Commit 3569ae1

Browse files
author
Josh Habdas
committed
Add custom prop type validator childrenOfTypesOnly
1 parent d624f49 commit 3569ae1

4 files changed

Lines changed: 29 additions & 17 deletions

File tree

src/collections/Table/Table.js

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,13 @@
11
import _ from 'lodash';
22
import React, {Children, Component, PropTypes} from 'react';
33
import classNames from 'classnames';
4-
import TableColumn from './TableColumn';
4+
import {childrenOfTypesOnly} from '../../utils/customPropTypes';
55
import META from 'src/utils/Meta';
66

77
export default class Table extends Component {
88
static propTypes = {
99
basic: PropTypes.bool,
10-
children: (props, propName, componentName) => {
11-
let isValid = true;
12-
Children.forEach(props.children, (child) => {
13-
if (child.type !== TableColumn) {
14-
isValid = false;
15-
}
16-
});
17-
if (!isValid) {
18-
return new Error('`Table` must only have `TableColumn` children.');
19-
}
20-
},
10+
children: childrenOfTypesOnly(['TableColumn']),
2111
className: PropTypes.string,
2212
data: PropTypes.array,
2313
};

src/elements/Segment/Segments.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
import React, {Component, PropTypes} from 'react';
22
import classNames from 'classnames';
33
import META from 'src/utils/Meta';
4+
import {childrenOfTypesOnly} from '../../utils/customPropTypes';
45

56
export default class Segments extends Component {
67
static propTypes = {
7-
children: PropTypes.node,
8+
children: childrenOfTypesOnly(['Segment', 'Segments']),
89
className: PropTypes.string,
910
};
1011

src/utils/customPropTypes.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,31 @@
1+
import {Children} from 'react';
12
import _ from 'lodash';
23

34
const customPropTypes = {
5+
/*
6+
* Ensures children are of a certain type
7+
* Similar to `oneOfType` built-in validator
8+
* @param {Array<string>} allowedTypes Collection of allowed types
9+
* @returns {Array} containing children of the specified type
10+
*/
11+
childrenOfTypesOnly: (allowedTypes) => {
12+
return (props, propName, componentName) => {
13+
const {children} = props;
14+
const disallowed = Children.map(children, child => {
15+
return _.includes(allowedTypes, _.get(child, 'type._meta.name')) ? null : child;
16+
});
17+
if (disallowed && disallowed.length !== 0) {
18+
throw new Error(
19+
`\`${componentName}\` should only have children of type \`${allowedTypes}\`.`);
20+
}
21+
};
22+
},
23+
/*
24+
* Verifies exclusivity of a given prop type
25+
* @param {string} exclusives property used in exclusivity check
26+
* @throws {Error} if props not mutually exclusive
27+
* @returns no-op
28+
*/
429
mutuallyExclusive: exclusives => {
530
return (props, propName, componentName) => {
631
_.forEach(exclusives, exclusiveProp => {

test/specs/elements/Segment/Segments-test.js

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,4 @@ describe('Segments', () => {
3131
component.querySelectorAll('.sd-segment').length
3232
).to.equal(3);
3333
});
34-
35-
it('only allows children of type Segment', () => {
36-
37-
});
3834
});

0 commit comments

Comments
 (0)