-
-
Notifications
You must be signed in to change notification settings - Fork 454
Expand file tree
/
Copy pathpropTypes.js
More file actions
109 lines (99 loc) · 3.21 KB
/
propTypes.js
File metadata and controls
109 lines (99 loc) · 3.21 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
import { deepForEach } from './childrenDeepMap';
import { isTab, isTabList, isTabPanel } from './elementTypes';
export function childrenPropType(props, propName, componentName) {
let error;
let tabsCount = 0;
let panelsCount = 0;
let tabListFound = false;
const listTabs = [];
const children = props[propName];
deepForEach(children, (child) => {
if (isTabList(child)) {
if (
child.props &&
child.props.children &&
typeof child.props.children === 'object'
) {
deepForEach(child.props.children, (listChild) =>
listTabs.push(listChild),
);
}
if (tabListFound) {
error = new Error(
"Found multiple 'TabList' components inside 'Tabs'. Only one is allowed.",
);
}
tabListFound = true;
}
if (isTab(child)) {
if (!tabListFound || listTabs.indexOf(child) === -1) {
error = new Error(
"Found a 'Tab' component outside of the 'TabList' component. 'Tab' components " +
"have to be inside the 'TabList' component.",
);
}
tabsCount++;
} else if (isTabPanel(child)) {
panelsCount++;
}
});
if (!error && props.usePanel && tabsCount !== panelsCount) {
error = new Error(
`There should be an equal number of 'Tab' and 'TabPanel' in \`${componentName}\`. ` +
`Received ${tabsCount} 'Tab' and ${panelsCount} 'TabPanel'.`,
);
}
return error;
}
export function onSelectPropType(
props,
propName,
componentName,
location,
propFullName,
) {
const prop = props[propName];
const name = propFullName || propName;
let error = null;
if (prop && typeof prop !== 'function') {
error = new Error(
`Invalid ${location} \`${name}\` of type \`${typeof prop}\` supplied ` +
`to \`${componentName}\`, expected \`function\`.`,
);
} else if (props.selectedIndex != null && prop == null) {
error = new Error(
`The ${location} \`${name}\` is marked as required in \`${componentName}\`, but ` +
`its value is \`undefined\` or \`null\`.\n` +
`\`onSelect\` is required when \`selectedIndex\` is also set. Not doing so will ` +
`make the tabs not do anything, as \`selectedIndex\` indicates that you want to ` +
`handle the selected tab yourself.\n` +
`If you only want to set the inital tab replace \`selectedIndex\` with \`defaultIndex\`.`,
);
}
return error;
}
export function selectedIndexPropType(
props,
propName,
componentName,
location,
propFullName,
) {
const prop = props[propName];
const name = propFullName || propName;
let error = null;
if (prop != null && typeof prop !== 'number') {
error = new Error(
`Invalid ${location} \`${name}\` of type \`${typeof prop}\` supplied to ` +
`\`${componentName}\`, expected \`number\`.`,
);
} else if (props.defaultIndex != null && prop != null) {
return new Error(
`The ${location} \`${name}\` cannot be used together with \`defaultIndex\` ` +
`in \`${componentName}\`.\n` +
`Either remove \`${name}\` to let \`${componentName}\` handle the selected ` +
`tab internally or remove \`defaultIndex\` to handle it yourself.`,
);
}
return error;
}