Refactor Home so that Dev section chrome is reusable across pages
This commit is contained in:
		@@ -4,10 +4,8 @@ import {
 | 
			
		||||
    EtherscanLinkSuffixes,
 | 
			
		||||
    Link,
 | 
			
		||||
    MarkdownSection,
 | 
			
		||||
    NestedSidebarMenu,
 | 
			
		||||
    Networks,
 | 
			
		||||
    SectionHeader,
 | 
			
		||||
    Styles,
 | 
			
		||||
    utils as sharedUtils,
 | 
			
		||||
} from '@0xproject/react-shared';
 | 
			
		||||
import {
 | 
			
		||||
@@ -21,7 +19,6 @@ import {
 | 
			
		||||
    TypescriptMethod,
 | 
			
		||||
} from '@0xproject/types';
 | 
			
		||||
import * as _ from 'lodash';
 | 
			
		||||
import CircularProgress from 'material-ui/CircularProgress';
 | 
			
		||||
import * as React from 'react';
 | 
			
		||||
import * as semver from 'semver';
 | 
			
		||||
 | 
			
		||||
@@ -43,26 +40,20 @@ const networkNameToColor: { [network: string]: string } = {
 | 
			
		||||
    [Networks.Rinkeby]: colors.darkYellow,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export interface DocumentationProps {
 | 
			
		||||
export interface DocReferenceProps {
 | 
			
		||||
    selectedVersion: string;
 | 
			
		||||
    availableVersions: string[];
 | 
			
		||||
    docsInfo: DocsInfo;
 | 
			
		||||
    sourceUrl: string;
 | 
			
		||||
    onVersionSelected: (semver: string) => void;
 | 
			
		||||
    docAgnosticFormat?: DocAgnosticFormat;
 | 
			
		||||
    sidebarHeader?: React.ReactNode;
 | 
			
		||||
    topBarHeight?: number;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface DocumentationState {
 | 
			
		||||
export interface DocReferenceState {
 | 
			
		||||
    isHoveringSidebar: boolean;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export class Documentation extends React.Component<DocumentationProps, DocumentationState> {
 | 
			
		||||
    public static defaultProps: Partial<DocumentationProps> = {
 | 
			
		||||
        topBarHeight: 0,
 | 
			
		||||
    };
 | 
			
		||||
    constructor(props: DocumentationProps) {
 | 
			
		||||
export class DocReference extends React.Component<DocReferenceProps, DocReferenceState> {
 | 
			
		||||
    constructor(props: DocReferenceProps) {
 | 
			
		||||
        super(props);
 | 
			
		||||
        this.state = {
 | 
			
		||||
            isHoveringSidebar: false,
 | 
			
		||||
@@ -74,112 +65,25 @@ export class Documentation extends React.Component<DocumentationProps, Documenta
 | 
			
		||||
    public componentWillUnmount(): void {
 | 
			
		||||
        window.removeEventListener('hashchange', this._onHashChanged.bind(this), false);
 | 
			
		||||
    }
 | 
			
		||||
    public componentDidUpdate(prevProps: DocumentationProps, _prevState: DocumentationState): void {
 | 
			
		||||
    public componentDidUpdate(prevProps: DocReferenceProps, _prevState: DocReferenceState): void {
 | 
			
		||||
        if (!_.isEqual(prevProps.docAgnosticFormat, this.props.docAgnosticFormat)) {
 | 
			
		||||
            const hash = window.location.hash.slice(1);
 | 
			
		||||
            sharedUtils.scrollToHash(hash, sharedConstants.SCROLL_CONTAINER_ID);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    public render(): React.ReactNode {
 | 
			
		||||
        const styles: Styles = {
 | 
			
		||||
            mainContainers: {
 | 
			
		||||
                position: 'absolute',
 | 
			
		||||
                top: 1,
 | 
			
		||||
                left: 0,
 | 
			
		||||
                bottom: 0,
 | 
			
		||||
                right: 0,
 | 
			
		||||
                overflowX: 'hidden',
 | 
			
		||||
                overflowY: 'scroll',
 | 
			
		||||
                minHeight: `calc(100vh - ${this.props.topBarHeight}px)`,
 | 
			
		||||
                WebkitOverflowScrolling: 'touch',
 | 
			
		||||
            },
 | 
			
		||||
            menuContainer: {
 | 
			
		||||
                borderColor: colors.grey300,
 | 
			
		||||
                maxWidth: 330,
 | 
			
		||||
                marginLeft: 20,
 | 
			
		||||
            },
 | 
			
		||||
        };
 | 
			
		||||
        const sectionNameToLinks = this.props.docsInfo.getSectionNameToLinks();
 | 
			
		||||
        const subsectionNameToLinks = this.props.docsInfo.getSubsectionNameToLinks(this.props.docAgnosticFormat);
 | 
			
		||||
        return (
 | 
			
		||||
            <div>
 | 
			
		||||
                {_.isUndefined(this.props.docAgnosticFormat) ? (
 | 
			
		||||
                    this._renderLoading(styles.mainContainers)
 | 
			
		||||
                ) : (
 | 
			
		||||
                    <div style={{ width: '100%', height: '100%', backgroundColor: colors.gray40 }}>
 | 
			
		||||
                        <div
 | 
			
		||||
                            className="mx-auto max-width-4 flex"
 | 
			
		||||
                            style={{ color: colors.grey800, height: `calc(100vh - ${this.props.topBarHeight}px)` }}
 | 
			
		||||
                        >
 | 
			
		||||
                            <div
 | 
			
		||||
                                className="relative sm-hide xs-hide"
 | 
			
		||||
                                style={{ width: '36%', height: `calc(100vh - ${this.props.topBarHeight}px)` }}
 | 
			
		||||
                            >
 | 
			
		||||
                                <div
 | 
			
		||||
                                    className="border-right absolute"
 | 
			
		||||
                                    style={{
 | 
			
		||||
                                        ...styles.menuContainer,
 | 
			
		||||
                                        ...styles.mainContainers,
 | 
			
		||||
                                        height: `calc(100vh - ${this.props.topBarHeight}px)`,
 | 
			
		||||
                                        overflow: this.state.isHoveringSidebar ? 'auto' : 'hidden',
 | 
			
		||||
                                    }}
 | 
			
		||||
                                    onMouseEnter={this._onSidebarHover.bind(this)}
 | 
			
		||||
                                    onMouseLeave={this._onSidebarHoverOff.bind(this)}
 | 
			
		||||
                                >
 | 
			
		||||
                                    <NestedSidebarMenu
 | 
			
		||||
                                        selectedVersion={this.props.selectedVersion}
 | 
			
		||||
                                        versions={this.props.availableVersions}
 | 
			
		||||
                                        sidebarHeader={this.props.sidebarHeader}
 | 
			
		||||
                                        sectionNameToLinks={sectionNameToLinks}
 | 
			
		||||
                                        subsectionNameToLinks={subsectionNameToLinks}
 | 
			
		||||
                                        onVersionSelected={this.props.onVersionSelected}
 | 
			
		||||
                                    />
 | 
			
		||||
                                </div>
 | 
			
		||||
                            </div>
 | 
			
		||||
                            <div
 | 
			
		||||
                                className="relative col lg-col-9 md-col-9 sm-col-12 col-12"
 | 
			
		||||
                                style={{ backgroundColor: colors.white }}
 | 
			
		||||
                            >
 | 
			
		||||
                                <div
 | 
			
		||||
                                    id={sharedConstants.SCROLL_CONTAINER_ID}
 | 
			
		||||
                                    style={styles.mainContainers}
 | 
			
		||||
                                    className="absolute px1"
 | 
			
		||||
                                >
 | 
			
		||||
                                    <div id={sharedConstants.SCROLL_TOP_ID} />
 | 
			
		||||
                                    {this._renderDocumentation()}
 | 
			
		||||
                                </div>
 | 
			
		||||
                            </div>
 | 
			
		||||
                        </div>
 | 
			
		||||
                    </div>
 | 
			
		||||
                )}
 | 
			
		||||
            </div>
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
    private _renderLoading(mainContainersStyles: React.CSSProperties): React.ReactNode {
 | 
			
		||||
        return (
 | 
			
		||||
            <div className="col col-12" style={mainContainersStyles}>
 | 
			
		||||
                <div
 | 
			
		||||
                    className="relative sm-px2 sm-pt2 sm-m1"
 | 
			
		||||
                    style={{ height: 122, top: '50%', transform: 'translateY(-50%)' }}
 | 
			
		||||
                >
 | 
			
		||||
                    <div className="center pb2">
 | 
			
		||||
                        <CircularProgress size={40} thickness={5} />
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <div className="center pt2" style={{ paddingBottom: 11 }}>
 | 
			
		||||
                        Loading documentation...
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
            </div>
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
    private _renderDocumentation(): React.ReactNode {
 | 
			
		||||
        const subMenus = _.values(this.props.docsInfo.menu);
 | 
			
		||||
        const subMenus = _.values(this.props.docsInfo.markdownMenu);
 | 
			
		||||
        const orderedSectionNames = _.flatten(subMenus);
 | 
			
		||||
 | 
			
		||||
        const typeDefinitionByName = this.props.docsInfo.getTypeDefinitionsByName(this.props.docAgnosticFormat);
 | 
			
		||||
        const renderedSections = _.map(orderedSectionNames, this._renderSection.bind(this, typeDefinitionByName));
 | 
			
		||||
 | 
			
		||||
        return renderedSections;
 | 
			
		||||
        return (
 | 
			
		||||
            <div>
 | 
			
		||||
                <div id={sharedConstants.SCROLL_TOP_ID} />
 | 
			
		||||
                {renderedSections}
 | 
			
		||||
            </div>
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
    private _renderSection(typeDefinitionByName: TypeDefinitionByName, sectionName: string): React.ReactNode {
 | 
			
		||||
        const markdownVersions = _.keys(this.props.docsInfo.sectionNameToMarkdownByVersion);
 | 
			
		||||
@@ -17,7 +17,7 @@ export class DocsInfo {
 | 
			
		||||
    public displayName: string;
 | 
			
		||||
    public packageName: string;
 | 
			
		||||
    public packageUrl: string;
 | 
			
		||||
    public menu: DocsMenu;
 | 
			
		||||
    public markdownMenu: DocsMenu;
 | 
			
		||||
    public typeSectionName: string;
 | 
			
		||||
    public sections: SectionsMap;
 | 
			
		||||
    public sectionNameToMarkdownByVersion: SectionNameToMarkdownByVersion;
 | 
			
		||||
@@ -25,7 +25,7 @@ export class DocsInfo {
 | 
			
		||||
    constructor(config: DocsInfoConfig) {
 | 
			
		||||
        this.id = config.id;
 | 
			
		||||
        this.type = config.type;
 | 
			
		||||
        this.menu = config.markdownMenu;
 | 
			
		||||
        this.markdownMenu = config.markdownMenu;
 | 
			
		||||
        this.displayName = config.displayName;
 | 
			
		||||
        this.packageName = config.packageName;
 | 
			
		||||
        this.packageUrl = config.packageUrl;
 | 
			
		||||
@@ -34,10 +34,31 @@ export class DocsInfo {
 | 
			
		||||
        this.sectionNameToMarkdownByVersion = config.sectionNameToMarkdownByVersion;
 | 
			
		||||
        this.contractsByVersionByNetworkId = config.contractsByVersionByNetworkId;
 | 
			
		||||
    }
 | 
			
		||||
    public getSubsectionNameToLinks(docAgnosticFormat?: DocAgnosticFormat): ObjectMap<ALink[]> {
 | 
			
		||||
        const subsectionNameToLinks: ObjectMap<ALink[]> = {};
 | 
			
		||||
    public getTypeDefinitionsByName(docAgnosticFormat: DocAgnosticFormat): { [name: string]: TypeDefinitionByName } {
 | 
			
		||||
        if (_.isUndefined(docAgnosticFormat[this.typeSectionName])) {
 | 
			
		||||
            return {};
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        const section = docAgnosticFormat[this.typeSectionName];
 | 
			
		||||
        const typeDefinitionByName = _.keyBy(section.types, 'name') as any;
 | 
			
		||||
        return typeDefinitionByName;
 | 
			
		||||
    }
 | 
			
		||||
    public getSectionNameToLinks(docAgnosticFormat: DocAgnosticFormat): ObjectMap<ALink[]> {
 | 
			
		||||
        const sectionNameToLinks: ObjectMap<ALink[]> = {};
 | 
			
		||||
        _.each(this.markdownMenu, (linkTitles, sectionName) => {
 | 
			
		||||
            sectionNameToLinks[sectionName] = [];
 | 
			
		||||
            _.each(linkTitles, linkTitle => {
 | 
			
		||||
                const to = sharedUtils.getIdFromName(linkTitle);
 | 
			
		||||
                const links = sectionNameToLinks[sectionName];
 | 
			
		||||
                links.push({
 | 
			
		||||
                    title: linkTitle,
 | 
			
		||||
                    to,
 | 
			
		||||
                });
 | 
			
		||||
            });
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        if (_.isUndefined(docAgnosticFormat)) {
 | 
			
		||||
            return subsectionNameToLinks;
 | 
			
		||||
            return sectionNameToLinks;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        const docSections = _.keys(this.sections);
 | 
			
		||||
@@ -64,7 +85,7 @@ export class DocsInfo {
 | 
			
		||||
                        title: typeName,
 | 
			
		||||
                    };
 | 
			
		||||
                });
 | 
			
		||||
                subsectionNameToLinks[sectionName] = typeLinks;
 | 
			
		||||
                sectionNameToLinks[sectionName] = typeLinks;
 | 
			
		||||
            } else if (isExportedFunctionSection) {
 | 
			
		||||
                // Noop so that we don't have the method listed underneath itself.
 | 
			
		||||
            } else {
 | 
			
		||||
@@ -88,33 +109,9 @@ export class DocsInfo {
 | 
			
		||||
                    };
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                subsectionNameToLinks[sectionName] = links;
 | 
			
		||||
                sectionNameToLinks[sectionName] = links;
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
        return subsectionNameToLinks;
 | 
			
		||||
    }
 | 
			
		||||
    public getTypeDefinitionsByName(docAgnosticFormat: DocAgnosticFormat): { [name: string]: TypeDefinitionByName } {
 | 
			
		||||
        if (_.isUndefined(docAgnosticFormat[this.typeSectionName])) {
 | 
			
		||||
            return {};
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        const section = docAgnosticFormat[this.typeSectionName];
 | 
			
		||||
        const typeDefinitionByName = _.keyBy(section.types, 'name') as any;
 | 
			
		||||
        return typeDefinitionByName;
 | 
			
		||||
    }
 | 
			
		||||
    public getSectionNameToLinks(): ObjectMap<ALink[]> {
 | 
			
		||||
        const sectionNameToLinks: ObjectMap<ALink[]> = {};
 | 
			
		||||
        _.each(this.menu, (linkTitles, sectionName) => {
 | 
			
		||||
            sectionNameToLinks[sectionName] = [];
 | 
			
		||||
            _.each(linkTitles, linkTitle => {
 | 
			
		||||
                const to = sharedUtils.getIdFromName(linkTitle);
 | 
			
		||||
                const links = sectionNameToLinks[sectionName];
 | 
			
		||||
                links.push({
 | 
			
		||||
                    title: linkTitle,
 | 
			
		||||
                    to,
 | 
			
		||||
                });
 | 
			
		||||
            });
 | 
			
		||||
        });
 | 
			
		||||
        return sectionNameToLinks;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -5,7 +5,7 @@ export { DocAgnosticFormat, GeneratedDocJson } from '@0xproject/types';
 | 
			
		||||
export { Badge } from './components/badge';
 | 
			
		||||
export { Comment } from './components/comment';
 | 
			
		||||
export { CustomEnum } from './components/custom_enum';
 | 
			
		||||
export { Documentation } from './components/documentation';
 | 
			
		||||
export { DocReference } from './components/doc_reference';
 | 
			
		||||
export { Enum } from './components/enum';
 | 
			
		||||
export { EventDefinition } from './components/event_definition';
 | 
			
		||||
export { Interface } from './components/interface';
 | 
			
		||||
 
 | 
			
		||||
@@ -95,7 +95,9 @@ export class TypeDocUtils {
 | 
			
		||||
 | 
			
		||||
        if (!_.isEmpty(this._externalExportToLink)) {
 | 
			
		||||
            this._docsInfo.sections[constants.EXTERNAL_EXPORTS_SECTION_NAME] = constants.EXTERNAL_EXPORTS_SECTION_NAME;
 | 
			
		||||
            this._docsInfo.menu[constants.EXTERNAL_EXPORTS_SECTION_NAME] = [constants.EXTERNAL_EXPORTS_SECTION_NAME];
 | 
			
		||||
            this._docsInfo.markdownMenu[constants.EXTERNAL_EXPORTS_SECTION_NAME] = [
 | 
			
		||||
                constants.EXTERNAL_EXPORTS_SECTION_NAME,
 | 
			
		||||
            ];
 | 
			
		||||
            const docSection: DocSection = {
 | 
			
		||||
                comment: 'This package also re-exports some third-party libraries for your convenience.',
 | 
			
		||||
                constructors: [],
 | 
			
		||||
@@ -119,7 +121,7 @@ export class TypeDocUtils {
 | 
			
		||||
                    case KindString.ObjectLiteral: {
 | 
			
		||||
                        sectionName = child.name;
 | 
			
		||||
                        this._docsInfo.sections[sectionName] = sectionName;
 | 
			
		||||
                        this._docsInfo.menu[sectionName] = [sectionName];
 | 
			
		||||
                        this._docsInfo.markdownMenu[sectionName] = [sectionName];
 | 
			
		||||
                        const entities = child.children;
 | 
			
		||||
                        const commentObj = child.comment;
 | 
			
		||||
                        const sectionComment = !_.isUndefined(commentObj) ? commentObj.shortText : '';
 | 
			
		||||
@@ -136,7 +138,7 @@ export class TypeDocUtils {
 | 
			
		||||
                    case KindString.Function: {
 | 
			
		||||
                        sectionName = child.name;
 | 
			
		||||
                        this._docsInfo.sections[sectionName] = sectionName;
 | 
			
		||||
                        this._docsInfo.menu[sectionName] = [sectionName];
 | 
			
		||||
                        this._docsInfo.markdownMenu[sectionName] = [sectionName];
 | 
			
		||||
                        const entities = [child];
 | 
			
		||||
                        const commentObj = child.comment;
 | 
			
		||||
                        const SectionComment = !_.isUndefined(commentObj) ? commentObj.shortText : '';
 | 
			
		||||
@@ -158,7 +160,7 @@ export class TypeDocUtils {
 | 
			
		||||
        });
 | 
			
		||||
        if (!_.isEmpty(typeEntities)) {
 | 
			
		||||
            this._docsInfo.sections[constants.TYPES_SECTION_NAME] = constants.TYPES_SECTION_NAME;
 | 
			
		||||
            this._docsInfo.menu[constants.TYPES_SECTION_NAME] = [constants.TYPES_SECTION_NAME];
 | 
			
		||||
            this._docsInfo.markdownMenu[constants.TYPES_SECTION_NAME] = [constants.TYPES_SECTION_NAME];
 | 
			
		||||
            const docSection = this._convertEntitiesToDocSection(typeEntities, constants.TYPES_SECTION_NAME);
 | 
			
		||||
            docAgnosticFormat[constants.TYPES_SECTION_NAME] = docSection;
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user