From de20ef1a49966153f25236ee68b186cd49f8dc20 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Fri, 12 Oct 2018 15:54:44 +0200 Subject: Refactor Home so that Dev section chrome is reusable across pages --- .../react-docs/src/components/doc_reference.tsx | 331 ++++++++++++++++ .../react-docs/src/components/documentation.tsx | 427 --------------------- 2 files changed, 331 insertions(+), 427 deletions(-) create mode 100644 packages/react-docs/src/components/doc_reference.tsx delete mode 100644 packages/react-docs/src/components/documentation.tsx (limited to 'packages/react-docs/src/components') diff --git a/packages/react-docs/src/components/doc_reference.tsx b/packages/react-docs/src/components/doc_reference.tsx new file mode 100644 index 000000000..38ec818db --- /dev/null +++ b/packages/react-docs/src/components/doc_reference.tsx @@ -0,0 +1,331 @@ +import { + colors, + constants as sharedConstants, + EtherscanLinkSuffixes, + Link, + MarkdownSection, + Networks, + SectionHeader, + utils as sharedUtils, +} from '@0xproject/react-shared'; +import { + DocAgnosticFormat, + Event, + ExternalExportToLink, + Property, + SolidityMethod, + TypeDefinitionByName, + TypescriptFunction, + TypescriptMethod, +} from '@0xproject/types'; +import * as _ from 'lodash'; +import * as React from 'react'; +import * as semver from 'semver'; + +import { DocsInfo } from '../docs_info'; +import { AddressByContractName, SupportedDocJson } from '../types'; +import { constants } from '../utils/constants'; + +import { Badge } from './badge'; +import { Comment } from './comment'; +import { EventDefinition } from './event_definition'; +import { PropertyBlock } from './property_block'; +import { SignatureBlock } from './signature_block'; +import { TypeDefinition } from './type_definition'; + +const networkNameToColor: { [network: string]: string } = { + [Networks.Kovan]: colors.purple, + [Networks.Ropsten]: colors.red, + [Networks.Mainnet]: colors.turquois, + [Networks.Rinkeby]: colors.darkYellow, +}; + +export interface DocReferenceProps { + selectedVersion: string; + availableVersions: string[]; + docsInfo: DocsInfo; + sourceUrl: string; + docAgnosticFormat?: DocAgnosticFormat; +} + +export interface DocReferenceState { + isHoveringSidebar: boolean; +} + +export class DocReference extends React.Component { + constructor(props: DocReferenceProps) { + super(props); + this.state = { + isHoveringSidebar: false, + }; + } + public componentDidMount(): void { + window.addEventListener('hashchange', this._onHashChanged.bind(this), false); + } + public componentWillUnmount(): void { + window.removeEventListener('hashchange', this._onHashChanged.bind(this), false); + } + 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 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} +
+ ); + } + private _renderSection(typeDefinitionByName: TypeDefinitionByName, sectionName: string): React.ReactNode { + const markdownVersions = _.keys(this.props.docsInfo.sectionNameToMarkdownByVersion); + const eligibleVersions = _.filter(markdownVersions, mdVersion => { + return semver.lte(mdVersion, this.props.selectedVersion); + }); + if (_.isEmpty(eligibleVersions)) { + throw new Error( + `No eligible markdown sections found for ${this.props.docsInfo.displayName} version ${ + this.props.selectedVersion + }.`, + ); + } + const sortedEligibleVersions = eligibleVersions.sort(semver.rcompare.bind(semver)); + const closestVersion = sortedEligibleVersions[0]; + const markdownFileIfExists = this.props.docsInfo.sectionNameToMarkdownByVersion[closestVersion][sectionName]; + if (!_.isUndefined(markdownFileIfExists)) { + return ( + + ); + } + + const docSection = this.props.docAgnosticFormat[sectionName]; + if (_.isUndefined(docSection)) { + return null; + } + + const isExportedFunctionSection = + docSection.functions.length === 1 && + _.isEmpty(docSection.types) && + _.isEmpty(docSection.methods) && + _.isEmpty(docSection.constructors) && + _.isEmpty(docSection.properties) && + _.isEmpty(docSection.events); + + const sortedTypes = _.sortBy(docSection.types, 'name'); + const typeDefs = _.map(sortedTypes, (customType, i) => { + return ( + + ); + }); + + const sortedProperties = _.sortBy(docSection.properties, 'name'); + const propertyDefs = _.map( + sortedProperties, + this._renderProperty.bind(this, sectionName, typeDefinitionByName), + ); + + const sortedMethods = _.sortBy(docSection.methods, 'name'); + const methodDefs = _.map(sortedMethods, method => { + return this._renderSignatureBlocks(method, sectionName, typeDefinitionByName); + }); + + const sortedFunctions = _.sortBy(docSection.functions, 'name'); + const functionDefs = _.map(sortedFunctions, func => { + return this._renderSignatureBlocks(func, sectionName, typeDefinitionByName); + }); + + const sortedEvents = _.sortBy(docSection.events, 'name'); + const eventDefs = _.map(sortedEvents, (event: Event, i: number) => { + return ( + + ); + }); + const headerStyle: React.CSSProperties = { + fontWeight: 100, + }; + return ( +
+
+
+ +
+ {this._renderNetworkBadgesIfExists(sectionName)} +
+ {docSection.comment && } + {!_.isEmpty(docSection.constructors) && ( +
+

Constructor

+ {this._renderConstructors(docSection.constructors, sectionName, typeDefinitionByName)} +
+ )} + {!_.isEmpty(docSection.properties) && ( +
+

Properties

+
{propertyDefs}
+
+ )} + {!_.isEmpty(docSection.methods) && ( +
+

Methods

+
{methodDefs}
+
+ )} + {!_.isEmpty(docSection.functions) && ( +
+ {!isExportedFunctionSection &&

Functions

} +
{functionDefs}
+
+ )} + {!_.isUndefined(docSection.events) && + docSection.events.length > 0 && ( +
+

Events

+
{eventDefs}
+
+ )} + {!_.isUndefined(docSection.externalExportToLink) && + this._renderExternalExports(docSection.externalExportToLink)} + {!_.isUndefined(typeDefs) && + typeDefs.length > 0 && ( +
+
{typeDefs}
+
+ )} +
+ ); + } + private _renderExternalExports(externalExportToLink: ExternalExportToLink): React.ReactNode { + const externalExports = _.map(externalExportToLink, (link: string, exportName: string) => { + return ( +
+ + {`import { `} + + {exportName} + + {` } from '${this.props.docsInfo.packageName}'`} + +
+ ); + }); + return
{externalExports}
; + } + private _renderNetworkBadgesIfExists(sectionName: string): React.ReactNode { + if (this.props.docsInfo.type !== SupportedDocJson.SolDoc) { + return null; + } + + const networkToAddressByContractName = this.props.docsInfo.contractsByVersionByNetworkId[ + this.props.selectedVersion + ]; + const badges = _.map( + networkToAddressByContractName, + (addressByContractName: AddressByContractName, networkName: string) => { + const contractAddress = addressByContractName[sectionName]; + if (_.isUndefined(contractAddress)) { + return null; + } + const linkIfExists = sharedUtils.getEtherScanLinkIfExists( + contractAddress, + sharedConstants.NETWORK_ID_BY_NAME[networkName], + EtherscanLinkSuffixes.Address, + ); + return ( +
+ + + +
+ ); + }, + ); + return badges; + } + private _renderConstructors( + constructors: SolidityMethod[] | TypescriptMethod[], + sectionName: string, + typeDefinitionByName: TypeDefinitionByName, + ): React.ReactNode { + const constructorDefs = _.map(constructors, constructor => { + return this._renderSignatureBlocks(constructor, sectionName, typeDefinitionByName); + }); + return
{constructorDefs}
; + } + private _renderProperty( + sectionName: string, + typeDefinitionByName: TypeDefinitionByName, + property: Property, + ): React.ReactNode { + return ( + + ); + } + private _renderSignatureBlocks( + method: SolidityMethod | TypescriptFunction | TypescriptMethod, + sectionName: string, + typeDefinitionByName: TypeDefinitionByName, + ): React.ReactNode { + return ( + + ); + } + private _onSidebarHover(_event: React.FormEvent): void { + this.setState({ + isHoveringSidebar: true, + }); + } + private _onSidebarHoverOff(): void { + this.setState({ + isHoveringSidebar: false, + }); + } + private _onHashChanged(_event: any): void { + const hash = window.location.hash.slice(1); + sharedUtils.scrollToHash(hash, sharedConstants.SCROLL_CONTAINER_ID); + } +} diff --git a/packages/react-docs/src/components/documentation.tsx b/packages/react-docs/src/components/documentation.tsx deleted file mode 100644 index 6a08d50e0..000000000 --- a/packages/react-docs/src/components/documentation.tsx +++ /dev/null @@ -1,427 +0,0 @@ -import { - colors, - constants as sharedConstants, - EtherscanLinkSuffixes, - Link, - MarkdownSection, - NestedSidebarMenu, - Networks, - SectionHeader, - Styles, - utils as sharedUtils, -} from '@0xproject/react-shared'; -import { - DocAgnosticFormat, - Event, - ExternalExportToLink, - Property, - SolidityMethod, - TypeDefinitionByName, - TypescriptFunction, - TypescriptMethod, -} from '@0xproject/types'; -import * as _ from 'lodash'; -import CircularProgress from 'material-ui/CircularProgress'; -import * as React from 'react'; -import * as semver from 'semver'; - -import { DocsInfo } from '../docs_info'; -import { AddressByContractName, SupportedDocJson } from '../types'; -import { constants } from '../utils/constants'; - -import { Badge } from './badge'; -import { Comment } from './comment'; -import { EventDefinition } from './event_definition'; -import { PropertyBlock } from './property_block'; -import { SignatureBlock } from './signature_block'; -import { TypeDefinition } from './type_definition'; - -const networkNameToColor: { [network: string]: string } = { - [Networks.Kovan]: colors.purple, - [Networks.Ropsten]: colors.red, - [Networks.Mainnet]: colors.turquois, - [Networks.Rinkeby]: colors.darkYellow, -}; - -export interface DocumentationProps { - selectedVersion: string; - availableVersions: string[]; - docsInfo: DocsInfo; - sourceUrl: string; - onVersionSelected: (semver: string) => void; - docAgnosticFormat?: DocAgnosticFormat; - sidebarHeader?: React.ReactNode; - topBarHeight?: number; -} - -export interface DocumentationState { - isHoveringSidebar: boolean; -} - -export class Documentation extends React.Component { - public static defaultProps: Partial = { - topBarHeight: 0, - }; - constructor(props: DocumentationProps) { - super(props); - this.state = { - isHoveringSidebar: false, - }; - } - public componentDidMount(): void { - window.addEventListener('hashchange', this._onHashChanged.bind(this), false); - } - public componentWillUnmount(): void { - window.removeEventListener('hashchange', this._onHashChanged.bind(this), false); - } - public componentDidUpdate(prevProps: DocumentationProps, _prevState: DocumentationState): 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 ( -
- {_.isUndefined(this.props.docAgnosticFormat) ? ( - this._renderLoading(styles.mainContainers) - ) : ( -
-
-
-
- -
-
-
-
-
- {this._renderDocumentation()} -
-
-
-
- )} -
- ); - } - private _renderLoading(mainContainersStyles: React.CSSProperties): React.ReactNode { - return ( -
-
-
- -
-
- Loading documentation... -
-
-
- ); - } - private _renderDocumentation(): React.ReactNode { - const subMenus = _.values(this.props.docsInfo.menu); - const orderedSectionNames = _.flatten(subMenus); - - const typeDefinitionByName = this.props.docsInfo.getTypeDefinitionsByName(this.props.docAgnosticFormat); - const renderedSections = _.map(orderedSectionNames, this._renderSection.bind(this, typeDefinitionByName)); - - return renderedSections; - } - private _renderSection(typeDefinitionByName: TypeDefinitionByName, sectionName: string): React.ReactNode { - const markdownVersions = _.keys(this.props.docsInfo.sectionNameToMarkdownByVersion); - const eligibleVersions = _.filter(markdownVersions, mdVersion => { - return semver.lte(mdVersion, this.props.selectedVersion); - }); - if (_.isEmpty(eligibleVersions)) { - throw new Error( - `No eligible markdown sections found for ${this.props.docsInfo.displayName} version ${ - this.props.selectedVersion - }.`, - ); - } - const sortedEligibleVersions = eligibleVersions.sort(semver.rcompare.bind(semver)); - const closestVersion = sortedEligibleVersions[0]; - const markdownFileIfExists = this.props.docsInfo.sectionNameToMarkdownByVersion[closestVersion][sectionName]; - if (!_.isUndefined(markdownFileIfExists)) { - return ( - - ); - } - - const docSection = this.props.docAgnosticFormat[sectionName]; - if (_.isUndefined(docSection)) { - return null; - } - - const isExportedFunctionSection = - docSection.functions.length === 1 && - _.isEmpty(docSection.types) && - _.isEmpty(docSection.methods) && - _.isEmpty(docSection.constructors) && - _.isEmpty(docSection.properties) && - _.isEmpty(docSection.events); - - const sortedTypes = _.sortBy(docSection.types, 'name'); - const typeDefs = _.map(sortedTypes, (customType, i) => { - return ( - - ); - }); - - const sortedProperties = _.sortBy(docSection.properties, 'name'); - const propertyDefs = _.map( - sortedProperties, - this._renderProperty.bind(this, sectionName, typeDefinitionByName), - ); - - const sortedMethods = _.sortBy(docSection.methods, 'name'); - const methodDefs = _.map(sortedMethods, method => { - return this._renderSignatureBlocks(method, sectionName, typeDefinitionByName); - }); - - const sortedFunctions = _.sortBy(docSection.functions, 'name'); - const functionDefs = _.map(sortedFunctions, func => { - return this._renderSignatureBlocks(func, sectionName, typeDefinitionByName); - }); - - const sortedEvents = _.sortBy(docSection.events, 'name'); - const eventDefs = _.map(sortedEvents, (event: Event, i: number) => { - return ( - - ); - }); - const headerStyle: React.CSSProperties = { - fontWeight: 100, - }; - return ( -
-
-
- -
- {this._renderNetworkBadgesIfExists(sectionName)} -
- {docSection.comment && } - {!_.isEmpty(docSection.constructors) && ( -
-

Constructor

- {this._renderConstructors(docSection.constructors, sectionName, typeDefinitionByName)} -
- )} - {!_.isEmpty(docSection.properties) && ( -
-

Properties

-
{propertyDefs}
-
- )} - {!_.isEmpty(docSection.methods) && ( -
-

Methods

-
{methodDefs}
-
- )} - {!_.isEmpty(docSection.functions) && ( -
- {!isExportedFunctionSection &&

Functions

} -
{functionDefs}
-
- )} - {!_.isUndefined(docSection.events) && - docSection.events.length > 0 && ( -
-

Events

-
{eventDefs}
-
- )} - {!_.isUndefined(docSection.externalExportToLink) && - this._renderExternalExports(docSection.externalExportToLink)} - {!_.isUndefined(typeDefs) && - typeDefs.length > 0 && ( -
-
{typeDefs}
-
- )} -
- ); - } - private _renderExternalExports(externalExportToLink: ExternalExportToLink): React.ReactNode { - const externalExports = _.map(externalExportToLink, (link: string, exportName: string) => { - return ( -
- - {`import { `} - - {exportName} - - {` } from '${this.props.docsInfo.packageName}'`} - -
- ); - }); - return
{externalExports}
; - } - private _renderNetworkBadgesIfExists(sectionName: string): React.ReactNode { - if (this.props.docsInfo.type !== SupportedDocJson.SolDoc) { - return null; - } - - const networkToAddressByContractName = this.props.docsInfo.contractsByVersionByNetworkId[ - this.props.selectedVersion - ]; - const badges = _.map( - networkToAddressByContractName, - (addressByContractName: AddressByContractName, networkName: string) => { - const contractAddress = addressByContractName[sectionName]; - if (_.isUndefined(contractAddress)) { - return null; - } - const linkIfExists = sharedUtils.getEtherScanLinkIfExists( - contractAddress, - sharedConstants.NETWORK_ID_BY_NAME[networkName], - EtherscanLinkSuffixes.Address, - ); - return ( -
- - - -
- ); - }, - ); - return badges; - } - private _renderConstructors( - constructors: SolidityMethod[] | TypescriptMethod[], - sectionName: string, - typeDefinitionByName: TypeDefinitionByName, - ): React.ReactNode { - const constructorDefs = _.map(constructors, constructor => { - return this._renderSignatureBlocks(constructor, sectionName, typeDefinitionByName); - }); - return
{constructorDefs}
; - } - private _renderProperty( - sectionName: string, - typeDefinitionByName: TypeDefinitionByName, - property: Property, - ): React.ReactNode { - return ( - - ); - } - private _renderSignatureBlocks( - method: SolidityMethod | TypescriptFunction | TypescriptMethod, - sectionName: string, - typeDefinitionByName: TypeDefinitionByName, - ): React.ReactNode { - return ( - - ); - } - private _onSidebarHover(_event: React.FormEvent): void { - this.setState({ - isHoveringSidebar: true, - }); - } - private _onSidebarHoverOff(): void { - this.setState({ - isHoveringSidebar: false, - }); - } - private _onHashChanged(_event: any): void { - const hash = window.location.hash.slice(1); - sharedUtils.scrollToHash(hash, sharedConstants.SCROLL_CONTAINER_ID); - } -} -- cgit