Files
protocol/packages/website/ts/pages/shared/nested_sidebar_menu.tsx
Fabio Berger e01c0f054d Merge branch 'development' into fix/docLinks
* development:
  Update and standardize contracts README
  Add to CHANGELOG
  Refactor toBaseUnitAmount so that it throws if user supplies unitAmount with too many decimals
  Make assertion stricter so that one cannot submit invalid baseUnit amounts to `toUnitAmount`
  Add some missed underscores, update changelog and comments
  Add new underscore-privates rule to @0xproject/tslint-config and fix lint errors

# Conflicts:
#	packages/website/ts/pages/documentation/documentation.tsx
#	packages/website/ts/pages/shared/nested_sidebar_menu.tsx
2017-12-21 21:24:54 +01:00

164 lines
6.5 KiB
TypeScript

import * as _ from 'lodash';
import MenuItem from 'material-ui/MenuItem';
import * as React from 'react';
import {Link as ScrollLink} from 'react-scroll';
import {VersionDropDown} from 'ts/pages/shared/version_drop_down';
import {MenuSubsectionsBySection, Styles} from 'ts/types';
import {colors} from 'ts/utils/colors';
import {constants} from 'ts/utils/constants';
import {utils} from 'ts/utils/utils';
interface NestedSidebarMenuProps {
topLevelMenu: {[topLevel: string]: string[]};
menuSubsectionsBySection: MenuSubsectionsBySection;
shouldDisplaySectionHeaders?: boolean;
onMenuItemClick?: () => void;
selectedVersion?: string;
versions?: string[];
docPath?: string;
isSectionHeaderClickable?: boolean;
}
interface NestedSidebarMenuState {}
const styles: Styles = {
menuItemWithHeaders: {
minHeight: 0,
},
menuItemWithoutHeaders: {
minHeight: 48,
},
menuItemInnerDivWithHeaders: {
lineHeight: 2,
},
};
export class NestedSidebarMenu extends React.Component<NestedSidebarMenuProps, NestedSidebarMenuState> {
public static defaultProps: Partial<NestedSidebarMenuProps> = {
shouldDisplaySectionHeaders: true,
onMenuItemClick: _.noop,
};
public render() {
const navigation = _.map(this.props.topLevelMenu, (menuItems: string[], sectionName: string) => {
const finalSectionName = sectionName.replace(/-/g, ' ');
if (this.props.shouldDisplaySectionHeaders) {
const id = utils.getIdFromName(sectionName);
return (
<div
key={`section-${sectionName}`}
className="py1"
>
<ScrollLink
to={id}
offset={-20}
duration={constants.DOCS_SCROLL_DURATION_MS}
containerId={constants.DOCS_CONTAINER_ID}
>
<div
style={{color: colors.grey, cursor: 'pointer'}}
className="pb1"
>
{finalSectionName.toUpperCase()}
</div>
</ScrollLink>
{this._renderMenuItems(menuItems)}
</div>
);
} else {
return (
<div key={`section-${sectionName}`} >
{this._renderMenuItems(menuItems)}
</div>
);
}
});
return (
<div>
{!_.isUndefined(this.props.versions) &&
!_.isUndefined(this.props.selectedVersion) &&
!_.isUndefined(this.props.docPath) &&
<VersionDropDown
selectedVersion={this.props.selectedVersion}
versions={this.props.versions}
docPath={this.props.docPath}
/>
}
{navigation}
</div>
);
}
private _renderMenuItems(menuItemNames: string[]): React.ReactNode[] {
const menuItemStyles = this.props.shouldDisplaySectionHeaders ?
styles.menuItemWithHeaders :
styles.menuItemWithoutHeaders;
const menuItemInnerDivStyles = this.props.shouldDisplaySectionHeaders ?
styles.menuItemInnerDivWithHeaders : {};
const menuItems = _.map(menuItemNames, menuItemName => {
const id = utils.getIdFromName(menuItemName);
return (
<div key={menuItemName}>
<ScrollLink
key={`menuItem-${menuItemName}`}
to={id}
offset={-10}
duration={constants.DOCS_SCROLL_DURATION_MS}
containerId={constants.DOCS_CONTAINER_ID}
>
<MenuItem
onTouchTap={this._onMenuItemClick.bind(this, menuItemName)}
style={menuItemStyles}
innerDivStyle={menuItemInnerDivStyles}
>
<span style={{textTransform: 'capitalize'}}>
{menuItemName}
</span>
</MenuItem>
</ScrollLink>
{this._renderMenuItemSubsections(menuItemName)}
</div>
);
});
return menuItems;
}
private _renderMenuItemSubsections(menuItemName: string): React.ReactNode {
if (_.isUndefined(this.props.menuSubsectionsBySection[menuItemName])) {
return null;
}
return this._renderMenuSubsectionsBySection(menuItemName, this.props.menuSubsectionsBySection[menuItemName]);
}
private _renderMenuSubsectionsBySection(menuItemName: string, entityNames: string[]): React.ReactNode {
return (
<ul style={{margin: 0, listStyleType: 'none', paddingLeft: 0}} key={menuItemName}>
{_.map(entityNames, entityName => {
const name = `${menuItemName}-${entityName}`;
const id = utils.getIdFromName(name);
return (
<li key={`menuItem-${entityName}`}>
<ScrollLink
to={id}
offset={0}
duration={constants.DOCS_SCROLL_DURATION_MS}
containerId={constants.DOCS_CONTAINER_ID}
onTouchTap={this._onMenuItemClick.bind(this, name)}
>
<MenuItem
onTouchTap={this._onMenuItemClick.bind(this, name)}
style={{minHeight: 35}}
innerDivStyle={{paddingLeft: 36, fontSize: 14, lineHeight: '35px'}}
>
{entityName}
</MenuItem>
</ScrollLink>
</li>
);
})}
</ul>
);
}
private _onMenuItemClick(name: string): void {
const id = utils.getIdFromName(name);
utils.setUrlHash(id);
this.props.onMenuItemClick();
}
}