lucid-ui
Version:
A UI component library from AppNexus.
88 lines (87 loc) • 3.74 kB
JavaScript
import _ from 'lodash';
import React from 'react';
import PropTypes from 'react-peek/prop-types';
import { lucidClassNames } from '../../util/style-helpers';
import { findTypes, getFirst, omitProps, } from '../../util/component-types';
import { buildModernHybridComponent } from '../../util/state-management';
import * as reducers from './VerticalTabs.reducers';
import { VerticalListMenuDumb as VerticalListMenu, } from '../VerticalListMenu/VerticalListMenu';
const cx = lucidClassNames.bind('&-VerticalTabs');
const { string, number, bool, func } = PropTypes;
const Tab = (_props) => null;
Tab.displayName = 'VerticalTabs.Tab';
Tab.peek = {
description: `
Content that will be rendered in a tab. Be sure to nest a Title
inside each Tab or provide it as a prop.
`,
};
Tab.propName = 'Tab';
Tab.propTypes = {
isSelected: bool `
Determines if the Tab is selected.
`,
};
/** Vertical Tabs Title Child Component */
const Title = (_props) => null;
Title.displayName = 'VerticalTabs.Title';
Title.peek = {
description: `
Titles can be provided as a child or prop to a Tab.
`,
};
Title.propName = 'Title';
/** Default props for the VerticalTabs component */
const defaultProps = {
selectedIndex: 0,
onSelect: _.noop,
};
class VerticalTabs extends React.Component {
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 (React.createElement("div", Object.assign({}, omitProps(passThroughs, undefined, _.keys(VerticalTabs.propTypes)), { className: cx('&', className) }),
React.createElement(VerticalListMenu, { selectedIndices: [actualSelectedIndex], onSelect: onSelect }, _.map(tabChildProps, (tabChildProp, index) => (React.createElement(VerticalListMenu.Item, { className: cx('&-Tab', {
'&-Tab-is-active': actualSelectedIndex === index,
}), key: index },
React.createElement("span", { className: cx('&-Tab-content') }, _.get(getFirst(tabChildProp, VerticalTabs.Title), 'props.children', '')))))),
React.createElement("div", { className: cx('&-content') }, _.get(tabChildProps, [actualSelectedIndex, 'children']))));
}
}
VerticalTabs.displayName = 'VerticalTabs';
VerticalTabs.propTypes = {
className: string `
Class names that are appended to the defaults.
`,
selectedIndex: number `
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.
`,
onSelect: func `
Callback for when the user clicks a tab. Called with the index of the tab
that was clicked. Signature: \`(index, { event, props}) => {}\`
`,
};
VerticalTabs.defaultProps = defaultProps;
VerticalTabs.reducers = reducers;
VerticalTabs.Tab = Tab;
VerticalTabs.Title = Title;
VerticalTabs.peek = {
description: `
\`VerticalTabs\` provides vertically tabbed navigation. It has a
flexible interface that allows tab content to be passed as regular
React children or through props.
`,
categories: ['navigation'],
madeFrom: ['VerticalListMenu'],
};
export default buildModernHybridComponent(VerticalTabs, { reducers });
export { VerticalTabs as VerticalTabsDumb };