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