diff options
Diffstat (limited to 'packages/react-docs/src')
-rw-r--r-- | packages/react-docs/src/components/comment.tsx | 4 | ||||
-rw-r--r-- | packages/react-docs/src/components/doc_reference.tsx (renamed from packages/react-docs/src/components/documentation.tsx) | 177 | ||||
-rw-r--r-- | packages/react-docs/src/components/signature_block.tsx | 2 | ||||
-rw-r--r-- | packages/react-docs/src/components/source_link.tsx | 8 | ||||
-rw-r--r-- | packages/react-docs/src/components/type.tsx | 73 | ||||
-rw-r--r-- | packages/react-docs/src/components/type_definition.tsx | 1 | ||||
-rw-r--r-- | packages/react-docs/src/docs_info.ts | 70 | ||||
-rw-r--r-- | packages/react-docs/src/index.ts | 2 | ||||
-rw-r--r-- | packages/react-docs/src/utils/typedoc_utils.ts | 10 |
9 files changed, 139 insertions, 208 deletions
diff --git a/packages/react-docs/src/components/comment.tsx b/packages/react-docs/src/components/comment.tsx index c3687c510..9c866e62c 100644 --- a/packages/react-docs/src/components/comment.tsx +++ b/packages/react-docs/src/components/comment.tsx @@ -1,4 +1,4 @@ -import { MarkdownCodeBlock } from '@0xproject/react-shared'; +import { colors, MarkdownCodeBlock } from '@0xproject/react-shared'; import * as React from 'react'; import * as ReactMarkdown from 'react-markdown'; @@ -13,7 +13,7 @@ const defaultProps = { export const Comment: React.SFC<CommentProps> = (props: CommentProps) => { return ( - <div className={`${props.className} comment`}> + <div className={`${props.className} comment`} style={{ color: colors.greyTheme }}> <ReactMarkdown source={props.comment} renderers={{ code: MarkdownCodeBlock }} /> </div> ); diff --git a/packages/react-docs/src/components/documentation.tsx b/packages/react-docs/src/components/doc_reference.tsx index a23111297..5fdcdd2d9 100644 --- a/packages/react-docs/src/components/documentation.tsx +++ b/packages/react-docs/src/components/doc_reference.tsx @@ -2,11 +2,11 @@ import { colors, constants as sharedConstants, EtherscanLinkSuffixes, + HeaderSizes, + Link, MarkdownSection, - NestedSidebarMenu, Networks, SectionHeader, - Styles, utils as sharedUtils, } from '@0xproject/react-shared'; import { @@ -20,7 +20,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'; @@ -42,142 +41,42 @@ 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 { - isHoveringSidebar: boolean; -} +export interface DocReferenceState {} -export class Documentation extends React.Component<DocumentationProps, DocumentationState> { - public static defaultProps: Partial<DocumentationProps> = { - topBarHeight: 0, - }; - constructor(props: DocumentationProps) { - super(props); - this.state = { - isHoveringSidebar: false, - }; - } +export class DocReference extends React.Component<DocReferenceProps, DocReferenceState> { 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 { + 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 menuSubsectionsBySection = this.props.docsInfo.getMenuSubsectionsBySection(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} - topLevelMenu={this.props.docsInfo.menu} - menuSubsectionsBySection={menuSubsectionsBySection} - 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); @@ -195,11 +94,16 @@ export class Documentation extends React.Component<DocumentationProps, Documenta const closestVersion = sortedEligibleVersions[0]; const markdownFileIfExists = this.props.docsInfo.sectionNameToMarkdownByVersion[closestVersion][sectionName]; if (!_.isUndefined(markdownFileIfExists)) { + // Special-case replace the `introduction` sectionName with the package name + const isIntroductionSection = sectionName === 'introduction'; + const headerSize = isIntroductionSection ? HeaderSizes.H1 : HeaderSizes.H3; return ( <MarkdownSection key={`markdown-section-${sectionName}`} sectionName={sectionName} + headerSize={headerSize} markdownContent={markdownFileIfExists} + alternativeSectionTitle={isIntroductionSection ? this.props.docsInfo.displayName : undefined} /> ); } @@ -290,7 +194,9 @@ export class Documentation extends React.Component<DocumentationProps, Documenta )} {!_.isEmpty(docSection.functions) && ( <div> - {!isExportedFunctionSection && <h2 style={headerStyle}>Functions</h2>} + {!isExportedFunctionSection && ( + <div style={{ ...headerStyle, fontSize: '1.5em' }}>Functions</div> + )} <div>{functionDefs}</div> </div> )} @@ -309,6 +215,15 @@ export class Documentation extends React.Component<DocumentationProps, Documenta <div>{typeDefs}</div> </div> )} + <div + style={{ + width: '100%', + height: 1, + backgroundColor: colors.grey300, + marginTop: 32, + marginBottom: 12, + }} + /> </div> ); } @@ -318,9 +233,9 @@ export class Documentation extends React.Component<DocumentationProps, Documenta <div className="pt2" key={`external-export-${exportName}`}> <code className={`hljs ${constants.TYPE_TO_SYNTAX[this.props.docsInfo.type]}`}> {`import { `} - <a href={link} target="_blank" style={{ color: colors.lightBlueA700, textDecoration: 'none' }}> + <Link to={link} shouldOpenInNewTab={true} fontColor={colors.lightBlueA700}> {exportName} - </a> + </Link> {` } from '${this.props.docsInfo.packageName}'`} </code> </div> @@ -349,14 +264,16 @@ export class Documentation extends React.Component<DocumentationProps, Documenta EtherscanLinkSuffixes.Address, ); return ( - <a - key={`badge-${networkName}-${sectionName}`} - href={linkIfExists} - target="_blank" - style={{ color: colors.white, textDecoration: 'none', marginTop: 8 }} - > - <Badge title={networkName} backgroundColor={networkNameToColor[networkName]} /> - </a> + <div style={{ marginTop: 8 }}> + <Link + key={`badge-${networkName}-${sectionName}`} + to={linkIfExists} + shouldOpenInNewTab={true} + fontColor={colors.white} + > + <Badge title={networkName} backgroundColor={networkNameToColor[networkName]} /> + </Link> + </div> ); }, ); @@ -406,16 +323,6 @@ export class Documentation extends React.Component<DocumentationProps, Documenta /> ); } - private _onSidebarHover(_event: React.FormEvent<HTMLInputElement>): 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/signature_block.tsx b/packages/react-docs/src/components/signature_block.tsx index 5ec82983a..819311953 100644 --- a/packages/react-docs/src/components/signature_block.tsx +++ b/packages/react-docs/src/components/signature_block.tsx @@ -55,7 +55,7 @@ export class SignatureBlock extends React.Component<SignatureBlockProps, Signatu <div id={`${this.props.sectionName}-${method.name}`} style={{ overflow: 'hidden', width: '100%' }} - className="pb4" + className="pb4 pt2" onMouseOver={this._setAnchorVisibility.bind(this, true)} onMouseOut={this._setAnchorVisibility.bind(this, false)} > diff --git a/packages/react-docs/src/components/source_link.tsx b/packages/react-docs/src/components/source_link.tsx index 3096ad8d5..c6dd09adb 100644 --- a/packages/react-docs/src/components/source_link.tsx +++ b/packages/react-docs/src/components/source_link.tsx @@ -1,4 +1,4 @@ -import { colors } from '@0xproject/react-shared'; +import { colors, Link } from '@0xproject/react-shared'; import { Source } from '@0xproject/types'; import * as React from 'react'; @@ -13,9 +13,9 @@ export const SourceLink = (props: SourceLinkProps) => { const sourceCodeUrl = `${props.sourceUrl}/${src.fileName}#L${src.line}`; return ( <div className="pt2" style={{ fontSize: 14 }}> - <a href={sourceCodeUrl} target="_blank" className="underline" style={{ color: colors.grey }}> - Source - </a> + <Link to={sourceCodeUrl} shouldOpenInNewTab={true} textDecoration="underline" fontColor={colors.grey}> + {'Source'} + </Link> </div> ); }; diff --git a/packages/react-docs/src/components/type.tsx b/packages/react-docs/src/components/type.tsx index 5c018f5dd..d579449f4 100644 --- a/packages/react-docs/src/components/type.tsx +++ b/packages/react-docs/src/components/type.tsx @@ -1,4 +1,4 @@ -import { colors, constants as sharedConstants, utils as sharedUtils } from '@0xproject/react-shared'; +import { colors, constants as sharedConstants, Link, utils as sharedUtils } from '@0xproject/react-shared'; import { Type as TypeDef, TypeDefinitionByName, TypeDocTypes } from '@0xproject/types'; import { errorUtils } from '@0xproject/utils'; import * as _ from 'lodash'; @@ -204,15 +204,12 @@ export const Type: React.SFC<TypeProps> = (props: TypeProps): any => { const isExportedClassReference = !!props.type.isExportedClassReference; const typeNameUrlIfExists = !_.isUndefined(props.type.externalLink) ? props.type.externalLink : undefined; if (!_.isUndefined(typeNameUrlIfExists)) { - typeName = ( - <a - href={typeNameUrlIfExists} - target="_blank" - className="text-decoration-none" - style={{ color: colors.lightBlueA700 }} - > + typeName = props.isInPopover ? ( + <span style={{ color: colors.lightBlueA700, cursor: 'pointer' }}>{typeName}</span> + ) : ( + <Link to={typeNameUrlIfExists} shouldOpenInNewTab={true} fontColor={colors.lightBlueA700}> {typeName} - </a> + </Link> ); } else if ( (isReference || isArray) && @@ -223,39 +220,41 @@ export const Type: React.SFC<TypeProps> = (props: TypeProps): any => { ? props.type.name : `${props.docsInfo.typeSectionName}-${typeName}`; typeName = ( - <ScrollLink - to={typeDefinitionAnchorId} - offset={0} - hashSpy={true} - duration={sharedConstants.DOCS_SCROLL_DURATION_MS} - containerId={sharedConstants.DOCS_CONTAINER_ID} - > + <span> {sharedUtils.isUserOnMobile() || props.isInPopover || isExportedClassReference ? ( <span style={{ color: colors.lightBlueA700, cursor: 'pointer' }}>{typeName}</span> ) : ( - <span - data-tip={true} - data-for={id} - style={{ - color: colors.lightBlueA700, - cursor: 'pointer', - display: 'inline-block', - }} + <ScrollLink + to={typeDefinitionAnchorId} + offset={0} + hashSpy={true} + duration={sharedConstants.DOCS_SCROLL_DURATION_MS} + containerId={sharedConstants.SCROLL_CONTAINER_ID} > - {typeName} - <ReactTooltip type="light" effect="solid" id={id} className="typeTooltip"> - <TypeDefinition - sectionName={props.sectionName} - customType={props.typeDefinitionByName[typeName as string]} - shouldAddId={false} - docsInfo={props.docsInfo} - typeDefinitionByName={props.typeDefinitionByName} - isInPopover={true} - /> - </ReactTooltip> - </span> + <span + data-tip={true} + data-for={id} + style={{ + color: colors.lightBlueA700, + cursor: 'pointer', + display: 'inline-block', + }} + > + {typeName} + <ReactTooltip type="light" effect="solid" id={id} className="typeTooltip"> + <TypeDefinition + sectionName={props.sectionName} + customType={props.typeDefinitionByName[typeName as string]} + shouldAddId={false} + docsInfo={props.docsInfo} + typeDefinitionByName={props.typeDefinitionByName} + isInPopover={true} + /> + </ReactTooltip> + </span> + </ScrollLink> )} - </ScrollLink> + </span> ); } return ( diff --git a/packages/react-docs/src/components/type_definition.tsx b/packages/react-docs/src/components/type_definition.tsx index 9a3e50a1b..3b64247f2 100644 --- a/packages/react-docs/src/components/type_definition.tsx +++ b/packages/react-docs/src/components/type_definition.tsx @@ -124,6 +124,7 @@ export class TypeDefinition extends React.Component<TypeDefinitionProps, TypeDef title={`${typePrefix} ${customType.name}`} id={this.props.shouldAddId ? typeDefinitionAnchorId : ''} shouldShowAnchor={this.state.shouldShowAnchor} + isDisabled={this.props.isInPopover} /> <div style={{ fontSize: 16 }}> <pre> diff --git a/packages/react-docs/src/docs_info.ts b/packages/react-docs/src/docs_info.ts index 092a8c266..08e7703df 100644 --- a/packages/react-docs/src/docs_info.ts +++ b/packages/react-docs/src/docs_info.ts @@ -1,5 +1,5 @@ -import { MenuSubsectionsBySection } from '@0xproject/react-shared'; -import { DocAgnosticFormat, TypeDefinitionByName } from '@0xproject/types'; +import { ALink, utils as sharedUtils } from '@0xproject/react-shared'; +import { DocAgnosticFormat, ObjectMap, TypeDefinitionByName } from '@0xproject/types'; import * as _ from 'lodash'; import { @@ -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 getMenuSubsectionsBySection(docAgnosticFormat?: DocAgnosticFormat): MenuSubsectionsBySection { - const menuSubsectionsBySection = {} as MenuSubsectionsBySection; + public getTypeDefinitionsByName(docAgnosticFormat: DocAgnosticFormat): ObjectMap<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 menuSubsectionsBySection; + return sectionNameToLinks; } const docSections = _.keys(this.sections); @@ -58,7 +79,13 @@ export class DocsInfo { if (sectionName === this.typeSectionName) { const sortedTypesNames = _.sortBy(docSection.types, 'name'); const typeNames = _.map(sortedTypesNames, t => t.name); - menuSubsectionsBySection[sectionName] = typeNames; + const typeLinks = _.map(typeNames, typeName => { + return { + to: `${sectionName}-${typeName}`, + title: typeName, + }; + }); + sectionNameToLinks[sectionName] = typeLinks; } else if (isExportedFunctionSection) { // Noop so that we don't have the method listed underneath itself. } else { @@ -73,23 +100,18 @@ export class DocsInfo { const methodNames = _.map(methodsSortedByName, m => m.name); const sortedFunctionNames = _.sortBy(docSection.functions, 'name'); const functionNames = _.map(sortedFunctionNames, m => m.name); - menuSubsectionsBySection[sectionName] = [ - ...eventNames, - ...propertyNames, - ...functionNames, - ...methodNames, - ]; + const names = [...eventNames, ...propertyNames, ...functionNames, ...methodNames]; + + const links = _.map(names, name => { + return { + to: `${sectionName}-${name}`, + title: name, + }; + }); + + sectionNameToLinks[sectionName] = links; } }); - return menuSubsectionsBySection; - } - 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; + return sectionNameToLinks; } } diff --git a/packages/react-docs/src/index.ts b/packages/react-docs/src/index.ts index f9382940c..504091b34 100644 --- a/packages/react-docs/src/index.ts +++ b/packages/react-docs/src/index.ts @@ -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'; diff --git a/packages/react-docs/src/utils/typedoc_utils.ts b/packages/react-docs/src/utils/typedoc_utils.ts index 19605d497..05c9dae55 100644 --- a/packages/react-docs/src/utils/typedoc_utils.ts +++ b/packages/react-docs/src/utils/typedoc_utils.ts @@ -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; } |