| 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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129 |
120x
120x
120x
120x
13x
13x
13x
13x
13x
19x
| import _ from 'lodash';
import React from 'react';
import { lucidClassNames } from '../../util/style-helpers';
import { createClass, getFirst, findTypes, omitProps } from '../../util/component-types';
import * as reducers from './VerticalTabs.reducers';
import VerticalListMenu from '../VerticalListMenu/VerticalListMenu';
const cx = lucidClassNames.bind('&-VerticalTabs');
const {
string,
number,
bool,
func,
} = React.PropTypes;
/**
*
* {"categories": ["navigation"], "madeFrom": ["VerticalListMenu"]}
*
* `VerticalTabs` provides vertically tabbed navigation. It has a flexible
* interface that allows tab content to be passed as regular React children or
* through props.
*/
const VerticalTabs = createClass({
displayName: 'VerticalTabs',
components: {
/**
* Content that will be rendered in a tab. Be sure to nest a Title inside
* each Tab or provide it as a prop.
*/
Tab: createClass({
displayName: 'VerticalTabs.Tab',
propName: 'Tab',
propTypes: {
/**
* Determines if the Tab is selected.
*/
isSelected: bool,
},
}),
/**
* Titles can be provided as a child or prop to a Tab.
*/
Title: createClass({
displayName: 'VerticalTabs.Title',
propName: 'Title',
}),
},
reducers,
propTypes: {
/**
* Class names that are appended to the defaults.
*/
className: string,
/**
* Indicates which of the `VerticalTabs.Tab` children is currently
* selected. The index of the last `VerticalTabs.Tab` child with
* `isSelected` equal to `true` takes precedence over this prop.
*/
selectedIndex: number,
/**
* Callback for when the user clicks a tab. Called with the index of the
* tab that was clicked.
*
* Signature: `(index, { event, props}) => {}`
*/
onSelect: func,
},
getDefaultProps() {
return {
selectedIndex: 0,
onSelect: _.noop,
};
},
render() {
const {
className,
onSelect,
selectedIndex,
...passThroughs,
} = this.props;
// Grab props array from each Tab
const tabChildProps = _.map(findTypes(this.props, VerticalTabs.Tab), 'props');
const selectedIndexFromChildren = _.findLastIndex(tabChildProps, {
isSelected: true,
});
const actualSelectedIndex = selectedIndexFromChildren !== -1
? selectedIndexFromChildren
: selectedIndex;
return (
<div
{...omitProps(passThroughs, VerticalTabs)}
className={cx('&', className)}
>
<VerticalListMenu
selectedIndices={[actualSelectedIndex]}
onSelect={onSelect}
>
{_.map(tabChildProps, (tabChildProp, index) => (
<VerticalListMenu.Item
className={cx('&-Tab', {'&-Tab-is-active': actualSelectedIndex === index})}
key={index}
>
<span className={cx('&-Tab-content')}>{_.get(getFirst(tabChildProp, VerticalTabs.Title), 'props.children', '')}</span>
</VerticalListMenu.Item>
))}
</VerticalListMenu>
<div className={cx('&-content')}>
{_.get(tabChildProps, [actualSelectedIndex, 'children'])}
</div>
</div>
);
},
});
export default VerticalTabs;
|