aboutsummaryrefslogtreecommitdiffstats
path: root/packages/react-docs
diff options
context:
space:
mode:
Diffstat (limited to 'packages/react-docs')
-rw-r--r--packages/react-docs/CHANGELOG.json81
-rw-r--r--packages/react-docs/CHANGELOG.md38
-rw-r--r--packages/react-docs/README.md18
-rw-r--r--packages/react-docs/package.json44
-rw-r--r--packages/react-docs/src/components/badge.tsx2
-rw-r--r--packages/react-docs/src/components/comment.tsx4
-rw-r--r--packages/react-docs/src/components/custom_enum.tsx4
-rw-r--r--packages/react-docs/src/components/doc_reference.tsx (renamed from packages/react-docs/src/components/documentation.tsx)285
-rw-r--r--packages/react-docs/src/components/event_definition.tsx11
-rw-r--r--packages/react-docs/src/components/interface.tsx38
-rw-r--r--packages/react-docs/src/components/property_block.tsx78
-rw-r--r--packages/react-docs/src/components/signature.tsx66
-rw-r--r--packages/react-docs/src/components/signature_block.tsx33
-rw-r--r--packages/react-docs/src/components/source_link.tsx11
-rw-r--r--packages/react-docs/src/components/type.tsx208
-rw-r--r--packages/react-docs/src/components/type_definition.tsx30
-rw-r--r--packages/react-docs/src/docs_info.ts137
-rw-r--r--packages/react-docs/src/index.ts7
-rw-r--r--packages/react-docs/src/monorepo_scripts/postpublish.ts8
-rw-r--r--packages/react-docs/src/types.ts236
-rw-r--r--packages/react-docs/src/utils/constants.ts3
-rw-r--r--packages/react-docs/src/utils/doxity_utils.ts176
-rw-r--r--packages/react-docs/src/utils/typedoc_utils.ts459
-rw-r--r--packages/react-docs/tsconfig.json5
-rw-r--r--packages/react-docs/tslint.json2
25 files changed, 933 insertions, 1051 deletions
diff --git a/packages/react-docs/CHANGELOG.json b/packages/react-docs/CHANGELOG.json
index 2b83b7fae..97485be96 100644
--- a/packages/react-docs/CHANGELOG.json
+++ b/packages/react-docs/CHANGELOG.json
@@ -1,5 +1,86 @@
[
{
+ "timestamp": 1539871071,
+ "version": "1.0.14",
+ "changes": [
+ {
+ "note": "Dependencies updated"
+ }
+ ]
+ },
+ {
+ "version": "1.0.13",
+ "changes": [
+ {
+ "note": "Dependencies updated"
+ }
+ ],
+ "timestamp": 1538693146
+ },
+ {
+ "timestamp": 1538157789,
+ "version": "1.0.12",
+ "changes": [
+ {
+ "note": "Dependencies updated"
+ }
+ ]
+ },
+ {
+ "timestamp": 1537907159,
+ "version": "1.0.11",
+ "changes": [
+ {
+ "note": "Dependencies updated"
+ }
+ ]
+ },
+ {
+ "timestamp": 1537875740,
+ "version": "1.0.10",
+ "changes": [
+ {
+ "note": "Dependencies updated"
+ }
+ ]
+ },
+ {
+ "timestamp": 1537541580,
+ "version": "1.0.9",
+ "changes": [
+ {
+ "note": "Dependencies updated"
+ }
+ ]
+ },
+ {
+ "timestamp": 1536142250,
+ "version": "1.0.8",
+ "changes": [
+ {
+ "note": "Dependencies updated"
+ }
+ ]
+ },
+ {
+ "timestamp": 1535377027,
+ "version": "1.0.7",
+ "changes": [
+ {
+ "note": "Dependencies updated"
+ }
+ ]
+ },
+ {
+ "timestamp": 1535133899,
+ "version": "1.0.6",
+ "changes": [
+ {
+ "note": "Dependencies updated"
+ }
+ ]
+ },
+ {
"timestamp": 1534210131,
"version": "1.0.5",
"changes": [
diff --git a/packages/react-docs/CHANGELOG.md b/packages/react-docs/CHANGELOG.md
index 38d2451dd..096bd8460 100644
--- a/packages/react-docs/CHANGELOG.md
+++ b/packages/react-docs/CHANGELOG.md
@@ -5,7 +5,43 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
-## v1.0.5 - _August 13, 2018_
+## v1.0.14 - _October 18, 2018_
+
+ * Dependencies updated
+
+## v1.0.13 - _October 4, 2018_
+
+ * Dependencies updated
+
+## v1.0.12 - _September 28, 2018_
+
+ * Dependencies updated
+
+## v1.0.11 - _September 25, 2018_
+
+ * Dependencies updated
+
+## v1.0.10 - _September 25, 2018_
+
+ * Dependencies updated
+
+## v1.0.9 - _September 21, 2018_
+
+ * Dependencies updated
+
+## v1.0.8 - _September 5, 2018_
+
+ * Dependencies updated
+
+## v1.0.7 - _August 27, 2018_
+
+ * Dependencies updated
+
+## v1.0.6 - _August 24, 2018_
+
+ * Dependencies updated
+
+## v1.0.5 - _August 14, 2018_
* Dependencies updated
diff --git a/packages/react-docs/README.md b/packages/react-docs/README.md
index c0efc4a0b..19c092e4d 100644
--- a/packages/react-docs/README.md
+++ b/packages/react-docs/README.md
@@ -1,6 +1,8 @@
-## @0xproject/react-docs
+## @0x/react-docs
-A full-page React component for rendering beautiful documentation for Solidity and Typescript code generated with [TypeDoc](http://typedoc.org/) or [Doxity](https://github.com/0xproject/doxity). See a [live example](http://react-docs-example.s3-website-us-east-1.amazonaws.com/).
+#### WARNING: Alpha software. Expect things to break when trying to use.
+
+A full-page React component for rendering beautiful documentation for Solidity and Typescript code generated with [TypeDoc](http://typedoc.org/) or [sol-doc](https://github.com/0xProject/0x-monorepo/tree/development/packages/sol-doc).
<div style="text-align: center;">
<img src="https://s3.eu-west-2.amazonaws.com/0x-wiki-images/screenshot.png" style="padding-bottom: 20px; padding-top: 20px;" width="80%" />
@@ -22,13 +24,11 @@ A full-page React component for rendering beautiful documentation for Solidity a
## Installation
```bash
-yarn add @0xproject/react-docs
+yarn add @0x/react-docs
```
## Usage
-View the [live example](http://react-docs-example.s3-website-us-east-1.amazonaws.com/) that renders the [@0xproject/web3-wrapper](https://github.com/0xProject/0x-monorepo/tree/development/packages/web3-wrapper) Typescript package. It's source code is in the [react-docs-example](https://github.com/0xProject/0x-monorepo/tree/development/packages/react-docs-example) 0x monorepo subpackage.
-
This package exposes both a single `Documentation` react component that will render a docs page, as well as all of it's sub-components in case someone wants to build their own layout.
Currently this package still has some external dependencies outside of the `Documentation` component, so please start your project off by copying the [react-docs-example](https://github.com/0xProject/0x-monorepo/tree/development/packages/react-docs-example) directory and modifying it there. If you need changes in the [react-docs](https://github.com/0xProject/0x-monorepo/tree/development/packages/react-docs) package, fork the 0x monorepo, make the required changes and submit a PR. Until we merge it, you can have your project depend on your own custom fork.
@@ -37,7 +37,7 @@ If your project is in [TypeScript](https://www.typescriptlang.org/), add the fol
```json
"compilerOptions": {
- "typeRoots": ["node_modules/@0xproject/typescript-typings/types", "node_modules/@types"],
+ "typeRoots": ["node_modules/@0x/typescript-typings/types", "node_modules/@types"],
}
```
@@ -47,7 +47,7 @@ Feel free to contribute to these improvements!
* Allow user to pass in styling for all major elements similar to [Material-UI](http://www.material-ui.com/).
* Allow user to define an alternative font and have it change everywhere.
-* Add source links to Solidity docs (currently unsupported by Doxity).
+* Add source links to Solidity docs (currently unsupported by solc, which underlies sol-doc).
## Contributing
@@ -74,13 +74,13 @@ yarn install
To build this package and all other monorepo packages that it depends on, run the following from the monorepo root directory:
```bash
-PKG=@0xproject/react-docs yarn build
+PKG=@0x/react-docs yarn build
```
Or continuously rebuild on change:
```bash
-PKG=@0xproject/react-docs yarn watch
+PKG=@0x/react-docs yarn watch
```
### Clean
diff --git a/packages/react-docs/package.json b/packages/react-docs/package.json
index f09bb64a0..e234b0479 100644
--- a/packages/react-docs/package.json
+++ b/packages/react-docs/package.json
@@ -1,18 +1,17 @@
{
- "name": "@0xproject/react-docs",
- "version": "1.0.5",
+ "name": "@0x/react-docs",
+ "version": "1.0.14",
"engines": {
"node": ">=6.12"
},
- "description": "React documentation component for rendering TypeDoc & Doxity generated JSON",
+ "description": "React documentation component for rendering TypeDoc & sol-doc generated JSON",
"main": "lib/index.js",
"types": "lib/index.d.ts",
"scripts": {
- "lint": "tslint --project .",
- "build": "tsc && copyfiles -u 2 './lib/monorepo_scripts/**/*' ./scripts",
- "watch_without_deps": "tsc -w",
- "clean": "shx rm -rf lib scripts",
- "manual:postpublish": "yarn build; node ./scripts/postpublish.js"
+ "lint": "tslint --format stylish --project .",
+ "build": "tsc -b",
+ "build:ci": "yarn build",
+ "clean": "shx rm -rf lib"
},
"author": "Fabio Berger",
"license": "Apache-2.0",
@@ -25,35 +24,36 @@
"url": "https://github.com/0xProject/0x-monorepo.git"
},
"devDependencies": {
- "@0xproject/dev-utils": "^1.0.4",
- "@0xproject/monorepo-scripts": "^1.0.5",
- "@0xproject/tslint-config": "^1.0.5",
+ "@0x/dev-utils": "^1.0.13",
+ "@0x/tslint-config": "^1.0.9",
"@types/compare-versions": "^3.0.0",
- "copyfiles": "^2.0.0",
+ "@types/styled-components": "^4.0.0",
"make-promises-safe": "^1.1.0",
"shx": "^0.2.2",
"tslint": "^5.9.1",
"typescript": "3.0.1"
},
"dependencies": {
- "@0xproject/react-shared": "^1.0.6",
- "@0xproject/utils": "^1.0.5",
+ "@0x/react-shared": "^1.0.17",
+ "@0x/types": "^1.2.0",
+ "@0x/utils": "^2.0.3",
"@types/lodash": "4.14.104",
- "@types/material-ui": "0.18.0",
- "@types/node": "^8.0.53",
+ "@types/material-ui": "^0.20.0",
+ "@types/node": "*",
"@types/react": "*",
"@types/react-dom": "*",
- "@types/react-scroll": "0.0.31",
+ "@types/react-scroll": "1.5.3",
"basscss": "^8.0.3",
"compare-versions": "^3.0.1",
"lodash": "^4.17.5",
- "material-ui": "^0.17.1",
- "react": "15.6.1",
- "react-dom": "15.6.1",
+ "material-ui": "^0.20.0",
+ "react": "^16.4.2",
+ "react-dom": "^16.4.2",
"react-markdown": "^3.2.2",
- "react-scroll": "^1.5.2",
+ "react-scroll": "0xproject/react-scroll#pr-330-and-replace-state",
"react-tooltip": "^3.2.7",
- "semver": "5.5.0"
+ "semver": "5.5.0",
+ "styled-components": "^3.3.0"
},
"publishConfig": {
"access": "public"
diff --git a/packages/react-docs/src/components/badge.tsx b/packages/react-docs/src/components/badge.tsx
index d34f8a0fc..e3d5be273 100644
--- a/packages/react-docs/src/components/badge.tsx
+++ b/packages/react-docs/src/components/badge.tsx
@@ -1,4 +1,4 @@
-import { Styles } from '@0xproject/react-shared';
+import { Styles } from '@0x/react-shared';
import * as React from 'react';
const styles: Styles = {
diff --git a/packages/react-docs/src/components/comment.tsx b/packages/react-docs/src/components/comment.tsx
index c3687c510..4d34f711e 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 '@0x/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/custom_enum.tsx b/packages/react-docs/src/components/custom_enum.tsx
index c4252d9e2..e971a012a 100644
--- a/packages/react-docs/src/components/custom_enum.tsx
+++ b/packages/react-docs/src/components/custom_enum.tsx
@@ -1,8 +1,8 @@
-import { logUtils } from '@0xproject/utils';
+import { logUtils } from '@0x/utils';
import * as _ from 'lodash';
import * as React from 'react';
-import { CustomType } from '../types';
+import { CustomType } from '@0x/types';
const STRING_ENUM_CODE_PREFIX = ' strEnum(';
diff --git a/packages/react-docs/src/components/documentation.tsx b/packages/react-docs/src/components/doc_reference.tsx
index ff33220d2..85547576b 100644
--- a/packages/react-docs/src/components/documentation.tsx
+++ b/packages/react-docs/src/components/doc_reference.tsx
@@ -2,38 +2,36 @@ import {
colors,
constants as sharedConstants,
EtherscanLinkSuffixes,
+ HeaderSizes,
+ Link,
MarkdownSection,
- NestedSidebarMenu,
Networks,
SectionHeader,
- Styles,
utils as sharedUtils,
-} from '@0xproject/react-shared';
-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';
+} from '@0x/react-shared';
import {
- AddressByContractName,
DocAgnosticFormat,
Event,
+ ExternalExportToLink,
Property,
SolidityMethod,
- SupportedDocJson,
TypeDefinitionByName,
TypescriptFunction,
TypescriptMethod,
-} from '../types';
+} from '@0x/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 { SourceLink } from './source_link';
-import { Type } from './type';
import { TypeDefinition } from './type_definition';
const networkNameToColor: { [network: string]: string } = {
@@ -43,142 +41,36 @@ 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,
- };
- }
- 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 {
+export class DocReference extends React.Component<DocReferenceProps, DocReferenceState> {
+ 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.getMenu(this.props.selectedVersion)}
- 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.getMenu());
+ 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);
@@ -196,11 +88,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}
/>
);
}
@@ -210,20 +107,33 @@ export class Documentation extends React.Component<DocumentationProps, Documenta
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 => {
+ const typeDefs = _.map(sortedTypes, (customType, i) => {
return (
<TypeDefinition
sectionName={sectionName}
- key={`type-${customType.name}`}
+ key={`type-${customType.name}-${i}`}
customType={customType}
docsInfo={this.props.docsInfo}
+ typeDefinitionByName={typeDefinitionByName}
+ isInPopover={false}
/>
);
});
const sortedProperties = _.sortBy(docSection.properties, 'name');
- const propertyDefs = _.map(sortedProperties, this._renderProperty.bind(this, sectionName));
+ const propertyDefs = _.map(
+ sortedProperties,
+ this._renderProperty.bind(this, sectionName, typeDefinitionByName),
+ );
const sortedMethods = _.sortBy(docSection.methods, 'name');
const methodDefs = _.map(sortedMethods, method => {
@@ -258,13 +168,12 @@ export class Documentation extends React.Component<DocumentationProps, Documenta
{this._renderNetworkBadgesIfExists(sectionName)}
</div>
{docSection.comment && <Comment comment={docSection.comment} />}
- {!_.isEmpty(docSection.constructors) &&
- this.props.docsInfo.isVisibleConstructor(sectionName) && (
- <div>
- <h2 style={headerStyle}>Constructor</h2>
- {this._renderConstructors(docSection.constructors, sectionName, typeDefinitionByName)}
- </div>
- )}
+ {!_.isEmpty(docSection.constructors) && (
+ <div>
+ <h2 style={headerStyle}>Constructor</h2>
+ {this._renderConstructors(docSection.constructors, sectionName, typeDefinitionByName)}
+ </div>
+ )}
{!_.isEmpty(docSection.properties) && (
<div>
<h2 style={headerStyle}>Properties</h2>
@@ -279,7 +188,9 @@ export class Documentation extends React.Component<DocumentationProps, Documenta
)}
{!_.isEmpty(docSection.functions) && (
<div>
- <h2 style={headerStyle}>Functions</h2>
+ {!isExportedFunctionSection && (
+ <div style={{ ...headerStyle, fontSize: '1.5em' }}>Functions</div>
+ )}
<div>{functionDefs}</div>
</div>
)}
@@ -290,17 +201,44 @@ export class Documentation extends React.Component<DocumentationProps, Documenta
<div>{eventDefs}</div>
</div>
)}
+ {!_.isUndefined(docSection.externalExportToLink) &&
+ this._renderExternalExports(docSection.externalExportToLink)}
{!_.isUndefined(typeDefs) &&
typeDefs.length > 0 && (
<div>
<div>{typeDefs}</div>
</div>
)}
+ <div
+ style={{
+ width: '100%',
+ height: 1,
+ backgroundColor: colors.grey300,
+ marginTop: 32,
+ marginBottom: 12,
+ }}
+ />
</div>
);
}
+ private _renderExternalExports(externalExportToLink: ExternalExportToLink): React.ReactNode {
+ const externalExports = _.map(externalExportToLink, (link: string, exportName: string) => {
+ return (
+ <div className="pt2" key={`external-export-${exportName}`}>
+ <code className={`hljs ${constants.TYPE_TO_SYNTAX[this.props.docsInfo.type]}`}>
+ {`import { `}
+ <Link to={link} shouldOpenInNewTab={true} fontColor={colors.lightBlueA700}>
+ {exportName}
+ </Link>
+ {` } from '${this.props.docsInfo.packageName}'`}
+ </code>
+ </div>
+ );
+ });
+ return <div>{externalExports}</div>;
+ }
private _renderNetworkBadgesIfExists(sectionName: string): React.ReactNode {
- if (this.props.docsInfo.type !== SupportedDocJson.Doxity) {
+ if (this.props.docsInfo.type !== SupportedDocJson.SolDoc) {
return null;
}
@@ -320,14 +258,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' }}
- >
- <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>
);
},
);
@@ -343,22 +283,21 @@ export class Documentation extends React.Component<DocumentationProps, Documenta
});
return <div>{constructorDefs}</div>;
}
- private _renderProperty(sectionName: string, property: Property): React.ReactNode {
+ private _renderProperty(
+ sectionName: string,
+ typeDefinitionByName: TypeDefinitionByName,
+ property: Property,
+ ): React.ReactNode {
return (
- <div key={`property-${property.name}-${property.type.name}`} className="pb3">
- <code className={`hljs ${constants.TYPE_TO_SYNTAX[this.props.docsInfo.type]}`}>
- {property.name}:{' '}
- <Type type={property.type} sectionName={sectionName} docsInfo={this.props.docsInfo} />
- </code>
- {property.source && (
- <SourceLink
- version={this.props.selectedVersion}
- source={property.source}
- sourceUrl={this.props.sourceUrl}
- />
- )}
- {property.comment && <Comment comment={property.comment} className="py2" />}
- </div>
+ <PropertyBlock
+ key={`property-${property.name}-${property.type.name}`}
+ property={property}
+ sectionName={sectionName}
+ docsInfo={this.props.docsInfo}
+ sourceUrl={this.props.sourceUrl}
+ selectedVersion={this.props.selectedVersion}
+ typeDefinitionByName={typeDefinitionByName}
+ />
);
}
private _renderSignatureBlocks(
@@ -378,18 +317,4 @@ 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/event_definition.tsx b/packages/react-docs/src/components/event_definition.tsx
index b4dc729a9..b76769788 100644
--- a/packages/react-docs/src/components/event_definition.tsx
+++ b/packages/react-docs/src/components/event_definition.tsx
@@ -1,9 +1,9 @@
-import { AnchorTitle, colors, HeaderSizes } from '@0xproject/react-shared';
+import { AnchorTitle, colors, HeaderSizes } from '@0x/react-shared';
+import { Event, EventArg } from '@0x/types';
import * as _ from 'lodash';
import * as React from 'react';
import { DocsInfo } from '../docs_info';
-import { Event, EventArg } from '../types';
import { Type } from './type';
@@ -53,7 +53,12 @@ export class EventDefinition extends React.Component<EventDefinitionProps, Event
const indexed = <span style={{ color: colors.green }}> indexed</span>;
const eventArgs = _.map(this.props.event.eventArgs, (eventArg: EventArg) => {
const type = (
- <Type type={eventArg.type} sectionName={this.props.sectionName} docsInfo={this.props.docsInfo} />
+ <Type
+ type={eventArg.type}
+ sectionName={this.props.sectionName}
+ docsInfo={this.props.docsInfo}
+ isInPopover={false}
+ />
);
return (
<span key={`eventArg-${eventArg.name}`}>
diff --git a/packages/react-docs/src/components/interface.tsx b/packages/react-docs/src/components/interface.tsx
index a881c7fec..0df44ca1c 100644
--- a/packages/react-docs/src/components/interface.tsx
+++ b/packages/react-docs/src/components/interface.tsx
@@ -1,27 +1,30 @@
import * as _ from 'lodash';
import * as React from 'react';
+import { CustomType, TypeDefinitionByName } from '@0x/types';
+
import { DocsInfo } from '../docs_info';
-import { CustomType, TypeDocTypes } from '../types';
import { Signature } from './signature';
import { Type } from './type';
+const defaultProps = {};
+
export interface InterfaceProps {
type: CustomType;
sectionName: string;
docsInfo: DocsInfo;
+ typeDefinitionByName: TypeDefinitionByName;
+ isInPopover: boolean;
}
-export const Interface = (props: InterfaceProps) => {
+export const Interface: React.SFC<InterfaceProps> = (props: InterfaceProps): any => {
const type = props.type;
- const properties = _.map(type.children, property => {
+ const properties = _.map(type.children, (property, i) => {
return (
- <span key={`property-${property.name}-${property.type}-${type.name}`}>
+ <span key={`property-${property.name}-${property.type}-${type.name}-${i}`}>
{property.name}:{' '}
- {property.type && property.type.typeDocType !== TypeDocTypes.Reflection ? (
- <Type type={property.type} sectionName={props.sectionName} docsInfo={props.docsInfo} />
- ) : (
+ {property.type && !_.isUndefined(property.type.method) ? (
<Signature
name={property.type.method.name}
returnType={property.type.method.returnType}
@@ -31,6 +34,16 @@ export const Interface = (props: InterfaceProps) => {
shouldHideMethodName={true}
shouldUseArrowSyntax={true}
docsInfo={props.docsInfo}
+ typeDefinitionByName={props.typeDefinitionByName}
+ isInPopover={props.isInPopover}
+ />
+ ) : (
+ <Type
+ type={property.type}
+ sectionName={props.sectionName}
+ docsInfo={props.docsInfo}
+ typeDefinitionByName={props.typeDefinitionByName}
+ isInPopover={props.isInPopover}
/>
)},
</span>
@@ -41,7 +54,14 @@ export const Interface = (props: InterfaceProps) => {
const is = type.indexSignature;
const param = (
<span key={`indexSigParams-${is.keyName}-${is.keyType}-${type.name}`}>
- {is.keyName}: <Type type={is.keyType} sectionName={props.sectionName} docsInfo={props.docsInfo} />
+ {is.keyName}:{' '}
+ <Type
+ type={is.keyType}
+ sectionName={props.sectionName}
+ docsInfo={props.docsInfo}
+ typeDefinitionByName={props.typeDefinitionByName}
+ isInPopover={props.isInPopover}
+ />
</span>
);
properties.push(
@@ -64,3 +84,5 @@ export const Interface = (props: InterfaceProps) => {
</span>
);
};
+
+Interface.defaultProps = defaultProps;
diff --git a/packages/react-docs/src/components/property_block.tsx b/packages/react-docs/src/components/property_block.tsx
new file mode 100644
index 000000000..d0bd84802
--- /dev/null
+++ b/packages/react-docs/src/components/property_block.tsx
@@ -0,0 +1,78 @@
+import { AnchorTitle, HeaderSizes } from '@0x/react-shared';
+import { Property, TypeDefinitionByName } from '@0x/types';
+import * as React from 'react';
+
+import { DocsInfo } from '../docs_info';
+import { constants } from '../utils/constants';
+
+import { Comment } from './comment';
+import { SourceLink } from './source_link';
+import { Type } from './type';
+
+export interface PropertyBlockProps {
+ property: Property;
+ sectionName: string;
+ docsInfo: DocsInfo;
+ sourceUrl: string;
+ selectedVersion: string;
+ typeDefinitionByName: TypeDefinitionByName;
+}
+
+export interface PropertyBlockState {
+ shouldShowAnchor: boolean;
+}
+
+export class PropertyBlock extends React.Component<PropertyBlockProps, PropertyBlockState> {
+ constructor(props: PropertyBlockProps) {
+ super(props);
+ this.state = {
+ shouldShowAnchor: false,
+ };
+ }
+ public render(): React.ReactNode {
+ const property = this.props.property;
+ const sectionName = this.props.sectionName;
+ return (
+ <div
+ id={`${this.props.sectionName}-${property.name}`}
+ className="pb4 pt2"
+ key={`property-${property.name}-${property.type.name}`}
+ onMouseOver={this._setAnchorVisibility.bind(this, true)}
+ onMouseOut={this._setAnchorVisibility.bind(this, false)}
+ >
+ <div className="pb2" style={{ lineHeight: 1.3 }}>
+ <AnchorTitle
+ headerSize={HeaderSizes.H3}
+ title={property.name}
+ id={`${sectionName}-${property.name}`}
+ shouldShowAnchor={this.state.shouldShowAnchor}
+ />
+ </div>
+ <code className={`hljs ${constants.TYPE_TO_SYNTAX[this.props.docsInfo.type]}`}>
+ {(property as any).callPath}
+ {property.name}:{' '}
+ <Type
+ type={property.type}
+ sectionName={sectionName}
+ docsInfo={this.props.docsInfo}
+ typeDefinitionByName={this.props.typeDefinitionByName}
+ isInPopover={false}
+ />
+ </code>
+ {property.source && (
+ <SourceLink
+ version={this.props.selectedVersion}
+ source={property.source}
+ sourceUrl={this.props.sourceUrl}
+ />
+ )}
+ {property.comment && <Comment comment={property.comment} className="py2" />}
+ </div>
+ );
+ }
+ private _setAnchorVisibility(shouldShowAnchor: boolean): void {
+ this.setState({
+ shouldShowAnchor,
+ });
+ }
+}
diff --git a/packages/react-docs/src/components/signature.tsx b/packages/react-docs/src/components/signature.tsx
index 77e9cc909..c229999b1 100644
--- a/packages/react-docs/src/components/signature.tsx
+++ b/packages/react-docs/src/components/signature.tsx
@@ -1,9 +1,9 @@
import * as _ from 'lodash';
import * as React from 'react';
+import { Parameter, Type as TypeDef, TypeDefinitionByName, TypeParameter } from '@0x/types';
+
import { DocsInfo } from '../docs_info';
-import { Parameter, Type as TypeDef, TypeDefinitionByName, TypeParameter } from '../types';
-import { constants } from '../utils/constants';
import { Type } from './type';
@@ -18,17 +18,27 @@ export interface SignatureProps {
typeParameter?: TypeParameter;
callPath?: string;
docsInfo: DocsInfo;
+ isInPopover: boolean;
+ isFallback?: boolean;
}
const defaultProps = {
shouldHideMethodName: false,
shouldUseArrowSyntax: false,
callPath: '',
+ isFallback: false,
};
export const Signature: React.SFC<SignatureProps> = (props: SignatureProps) => {
- const sectionName = constants.TYPES_SECTION_NAME;
- const parameters = renderParameters(props.parameters, props.docsInfo, sectionName, props.typeDefinitionByName);
+ const sectionName = props.sectionName;
+ const parameters = renderParameters(
+ props.parameters,
+ props.docsInfo,
+ sectionName,
+ props.isInPopover,
+ props.name,
+ props.typeDefinitionByName,
+ );
const paramStringArray: any[] = [];
// HACK: For now we don't put params on newlines if there are less then 2 of them.
// Ideally we would check the character length of the resulting method signature and
@@ -58,11 +68,17 @@ export const Signature: React.SFC<SignatureProps> = (props: SignatureProps) => {
const methodName = props.shouldHideMethodName ? '' : props.name;
const typeParameterIfExists = _.isUndefined(props.typeParameter)
? undefined
- : renderTypeParameter(props.typeParameter, props.docsInfo, sectionName, props.typeDefinitionByName);
+ : renderTypeParameter(
+ props.typeParameter,
+ props.docsInfo,
+ sectionName,
+ props.isInPopover,
+ props.typeDefinitionByName,
+ );
return (
<span style={{ fontSize: 15 }}>
{props.callPath}
- {methodName}
+ {props.isFallback ? '' : methodName}
{typeParameterIfExists}({hasMoreThenTwoParams && <br />}
{paramStringArray})
{props.returnType && (
@@ -73,6 +89,7 @@ export const Signature: React.SFC<SignatureProps> = (props: SignatureProps) => {
sectionName={sectionName}
typeDefinitionByName={props.typeDefinitionByName}
docsInfo={props.docsInfo}
+ isInPopover={props.isInPopover}
/>
</span>
)}
@@ -86,9 +103,11 @@ function renderParameters(
parameters: Parameter[],
docsInfo: DocsInfo,
sectionName: string,
+ isInPopover: boolean,
+ name: string,
typeDefinitionByName?: TypeDefinitionByName,
): React.ReactNode[] {
- const params = _.map(parameters, (p: Parameter) => {
+ const params = _.map(parameters, (p: Parameter, i: number) => {
const isOptional = p.isOptional;
const hasDefaultValue = !_.isUndefined(p.defaultValue);
const type = (
@@ -97,12 +116,18 @@ function renderParameters(
sectionName={sectionName}
typeDefinitionByName={typeDefinitionByName}
docsInfo={docsInfo}
+ isInPopover={isInPopover}
/>
);
return (
- <span key={`param-${p.type}-${p.name}`}>
- {p.name}
- {isOptional && '?'}: {type}
+ <span key={`param-${JSON.stringify(p.type)}-${name}-${i}`}>
+ {!_.isEmpty(p.name) && (
+ <span>
+ {p.name}
+ {isOptional && '?'}:{' '}
+ </span>
+ )}
+ {type}
{hasDefaultValue && ` = ${p.defaultValue}`}
</span>
);
@@ -114,17 +139,24 @@ function renderTypeParameter(
typeParameter: TypeParameter,
docsInfo: DocsInfo,
sectionName: string,
+ isInPopover: boolean,
typeDefinitionByName?: TypeDefinitionByName,
): React.ReactNode {
const typeParam = (
<span>
- {`<${typeParameter.name} extends `}
- <Type
- type={typeParameter.type}
- sectionName={sectionName}
- typeDefinitionByName={typeDefinitionByName}
- docsInfo={docsInfo}
- />
+ {`<${typeParameter.name}`}
+ {!_.isUndefined(typeParameter.type) && (
+ <span>
+ {' extends '}
+ <Type
+ type={typeParameter.type}
+ sectionName={sectionName}
+ typeDefinitionByName={typeDefinitionByName}
+ docsInfo={docsInfo}
+ isInPopover={isInPopover}
+ />
+ </span>
+ )}
{`>`}
</span>
);
diff --git a/packages/react-docs/src/components/signature_block.tsx b/packages/react-docs/src/components/signature_block.tsx
index 9e5198e16..7cdf19bb0 100644
--- a/packages/react-docs/src/components/signature_block.tsx
+++ b/packages/react-docs/src/components/signature_block.tsx
@@ -1,11 +1,10 @@
-import { AnchorTitle, colors, HeaderSizes, Styles } from '@0xproject/react-shared';
+import { AnchorTitle, colors, HeaderSizes, Styles } from '@0x/react-shared';
+import { Parameter, SolidityMethod, TypeDefinitionByName, TypescriptFunction, TypescriptMethod } from '@0x/types';
import * as _ from 'lodash';
import * as React from 'react';
import { DocsInfo } from '../docs_info';
-import { Parameter, SolidityMethod, TypeDefinitionByName, TypescriptFunction, TypescriptMethod } from '../types';
import { constants } from '../utils/constants';
-import { typeDocUtils } from '../utils/typedoc_utils';
import { Comment } from './comment';
import { Signature } from './signature';
@@ -27,7 +26,6 @@ export interface SignatureBlockState {
const styles: Styles = {
chip: {
fontSize: 13,
- backgroundColor: colors.lightBlueA700,
color: colors.white,
height: 11,
borderRadius: 14,
@@ -44,15 +42,14 @@ export class SignatureBlock extends React.Component<SignatureBlockProps, Signatu
}
public render(): React.ReactNode {
const method = this.props.method;
- if (typeDocUtils.isPrivateOrProtectedProperty(method.name)) {
- return null;
- }
+ const isFallback = (method as SolidityMethod).isFallback;
+ const hasExclusivelyNamedParams = !_.isUndefined(_.find(method.parameters, p => !_.isEmpty(p.name)));
return (
<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)}
>
@@ -61,10 +58,11 @@ export class SignatureBlock extends React.Component<SignatureBlockProps, Signatu
{(method as TypescriptMethod).isStatic && this._renderChip('Static')}
{(method as SolidityMethod).isConstant && this._renderChip('Constant')}
{(method as SolidityMethod).isPayable && this._renderChip('Payable')}
+ {isFallback && this._renderChip('Fallback', colors.lightGreenA700)}
<div style={{ lineHeight: 1.3 }}>
<AnchorTitle
headerSize={HeaderSizes.H3}
- title={method.name}
+ title={isFallback ? '' : method.name}
id={`${this.props.sectionName}-${method.name}`}
shouldShowAnchor={this.state.shouldShowAnchor}
/>
@@ -81,6 +79,8 @@ export class SignatureBlock extends React.Component<SignatureBlockProps, Signatu
sectionName={this.props.sectionName}
typeDefinitionByName={this.props.typeDefinitionByName}
docsInfo={this.props.docsInfo}
+ isInPopover={false}
+ isFallback={isFallback}
/>
</code>
{(method as TypescriptMethod).source && (
@@ -92,12 +92,13 @@ export class SignatureBlock extends React.Component<SignatureBlockProps, Signatu
)}
{method.comment && <Comment comment={method.comment} className="py2" />}
{method.parameters &&
- !_.isEmpty(method.parameters) && (
+ !_.isEmpty(method.parameters) &&
+ hasExclusivelyNamedParams && (
<div>
<h4 className="pb1 thin" style={{ borderBottom: '1px solid #e1e8ed' }}>
ARGUMENTS
</h4>
- {this._renderParameterDescriptions(method.parameters)}
+ {this._renderParameterDescriptions(method.parameters, method.name)}
</div>
)}
{method.returnComment && (
@@ -111,19 +112,19 @@ export class SignatureBlock extends React.Component<SignatureBlockProps, Signatu
</div>
);
}
- private _renderChip(text: string): React.ReactNode {
+ private _renderChip(text: string, backgroundColor: string = colors.lightBlueA700): React.ReactNode {
return (
- <div className="p1 mr1" style={styles.chip}>
+ <div className="p1 mr1" style={{ ...styles.chip, backgroundColor }}>
{text}
</div>
);
}
- private _renderParameterDescriptions(parameters: Parameter[]): React.ReactNode {
- const descriptions = _.map(parameters, parameter => {
+ private _renderParameterDescriptions(parameters: Parameter[], name: string): React.ReactNode {
+ const descriptions = _.map(parameters, (parameter: Parameter, i: number) => {
const isOptional = parameter.isOptional;
return (
<div
- key={`param-description-${parameter.name}`}
+ key={`param-description-${parameter.name}-${name}-${i}`}
className="flex pb1 mb2"
style={{ borderBottom: '1px solid #f0f4f7' }}
>
diff --git a/packages/react-docs/src/components/source_link.tsx b/packages/react-docs/src/components/source_link.tsx
index c60435ea6..6459824c2 100644
--- a/packages/react-docs/src/components/source_link.tsx
+++ b/packages/react-docs/src/components/source_link.tsx
@@ -1,8 +1,7 @@
-import { colors } from '@0xproject/react-shared';
+import { colors, Link } from '@0x/react-shared';
+import { Source } from '@0x/types';
import * as React from 'react';
-import { Source } from '../types';
-
export interface SourceLinkProps {
source: Source;
sourceUrl: string;
@@ -14,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 e453349ef..412b99b9d 100644
--- a/packages/react-docs/src/components/type.tsx
+++ b/packages/react-docs/src/components/type.tsx
@@ -1,26 +1,32 @@
-import { colors, constants as sharedConstants, utils as sharedUtils } from '@0xproject/react-shared';
-import { errorUtils } from '@0xproject/utils';
+import { colors, constants as sharedConstants, Link, utils as sharedUtils } from '@0x/react-shared';
+import { Type as TypeDef, TypeDefinitionByName, TypeDocTypes } from '@0x/types';
+import { errorUtils } from '@0x/utils';
import * as _ from 'lodash';
import * as React from 'react';
import { Link as ScrollLink } from 'react-scroll';
import * as ReactTooltip from 'react-tooltip';
import { DocsInfo } from '../docs_info';
-import { Type as TypeDef, TypeDefinitionByName, TypeDocTypes } from '../types';
import { Signature } from './signature';
import { TypeDefinition } from './type_definition';
+const basicJsTypes = ['string', 'number', 'undefined', 'null', 'boolean'];
+const basicSolidityTypes = ['bytes', 'bytes4', 'bytes32', 'uint8', 'uint256', 'address'];
+
+const defaultProps = {};
+
export interface TypeProps {
type: TypeDef;
docsInfo: DocsInfo;
sectionName: string;
typeDefinitionByName?: TypeDefinitionByName;
+ isInPopover: boolean;
}
// The return type needs to be `any` here so that we can recursively define <Type /> components within
// <Type /> components (e.g when rendering the union type).
-export function Type(props: TypeProps): any {
+export const Type: React.SFC<TypeProps> = (props: TypeProps): any => {
const type = props.type;
const isReference = type.typeDocType === TypeDocTypes.Reference;
const isArray = type.typeDocType === TypeDocTypes.Array;
@@ -43,10 +49,11 @@ export function Type(props: TypeProps): any {
<span>
<Type
key={key}
- type={arg.elementType}
+ type={arg}
sectionName={props.sectionName}
typeDefinitionByName={props.typeDefinitionByName}
docsInfo={props.docsInfo}
+ isInPopover={props.isInPopover}
/>[]
</span>
);
@@ -58,6 +65,7 @@ export function Type(props: TypeProps): any {
sectionName={props.sectionName}
typeDefinitionByName={props.typeDefinitionByName}
docsInfo={props.docsInfo}
+ isInPopover={props.isInPopover}
/>
);
return subType;
@@ -72,6 +80,9 @@ export function Type(props: TypeProps): any {
case TypeDocTypes.Array:
typeName = type.elementType.name;
+ if (_.includes(basicJsTypes, typeName) || _.includes(basicSolidityTypes, typeName)) {
+ typeNameColor = colors.orange;
+ }
break;
case TypeDocTypes.Union:
@@ -83,6 +94,7 @@ export function Type(props: TypeProps): any {
sectionName={props.sectionName}
typeDefinitionByName={props.typeDefinitionByName}
docsInfo={props.docsInfo}
+ isInPopover={props.isInPopover}
/>
);
});
@@ -92,19 +104,45 @@ export function Type(props: TypeProps): any {
break;
case TypeDocTypes.Reflection:
- typeName = (
- <Signature
- name={type.method.name}
- returnType={type.method.returnType}
- parameters={type.method.parameters}
- typeParameter={type.method.typeParameter}
- sectionName={props.sectionName}
- shouldHideMethodName={true}
- shouldUseArrowSyntax={true}
- docsInfo={props.docsInfo}
- typeDefinitionByName={props.typeDefinitionByName}
- />
- );
+ if (!_.isUndefined(type.method)) {
+ typeName = (
+ <Signature
+ name={type.method.name}
+ returnType={type.method.returnType}
+ parameters={type.method.parameters}
+ typeParameter={type.method.typeParameter}
+ sectionName={props.sectionName}
+ shouldHideMethodName={true}
+ shouldUseArrowSyntax={true}
+ docsInfo={props.docsInfo}
+ typeDefinitionByName={props.typeDefinitionByName}
+ isInPopover={props.isInPopover}
+ />
+ );
+ } else if (!_.isUndefined(type.indexSignature)) {
+ const is = type.indexSignature;
+ const param = (
+ <span key={`indexSigParams-${is.keyName}-${is.keyType}-${type.name}`}>
+ {is.keyName}:{' '}
+ <Type
+ type={is.keyType}
+ sectionName={props.sectionName}
+ docsInfo={props.docsInfo}
+ typeDefinitionByName={props.typeDefinitionByName}
+ isInPopover={props.isInPopover}
+ />
+ </span>
+ );
+ typeName = (
+ <span key={`indexSignature-${type.name}-${is.keyType.name}`}>
+ {'{'}[{param}]: {is.valueName}
+ {'}'}
+ </span>
+ );
+ } else {
+ throw new Error(`Unrecognized Reflection type that isn't a Method nor an Index Signature`);
+ }
+
break;
case TypeDocTypes.TypeParameter:
@@ -120,6 +158,7 @@ export function Type(props: TypeProps): any {
sectionName={props.sectionName}
typeDefinitionByName={props.typeDefinitionByName}
docsInfo={props.docsInfo}
+ isInPopover={props.isInPopover}
/>
);
});
@@ -128,6 +167,28 @@ export function Type(props: TypeProps): any {
});
break;
+ case TypeDocTypes.Tuple:
+ const tupleTypes = _.map(type.tupleElements, (t, i) => {
+ return (
+ <Type
+ key={`type-tuple-${t.name}-${t.typeDocType}-${i}`}
+ type={t}
+ sectionName={props.sectionName}
+ typeDefinitionByName={props.typeDefinitionByName}
+ docsInfo={props.docsInfo}
+ isInPopover={props.isInPopover}
+ />
+ );
+ });
+ typeName = (
+ <div>
+ [{_.reduce(tupleTypes, (prev: React.ReactNode, curr: React.ReactNode) => {
+ return [prev, ', ', curr];
+ })}]
+ </div>
+ );
+ break;
+
default:
throw errorUtils.spawnSwitchErr('type.typeDocType', type.typeDocType);
}
@@ -140,81 +201,60 @@ export function Type(props: TypeProps): any {
return [prev, ', ', curr];
});
- let typeNameUrlIfExists;
- let typePrefixIfExists;
- let sectionNameIfExists;
- if (!_.isUndefined(props.docsInfo.typeConfigs)) {
- typeNameUrlIfExists = !_.isUndefined(props.docsInfo.typeConfigs.typeNameToExternalLink)
- ? props.docsInfo.typeConfigs.typeNameToExternalLink[typeName as string]
- : undefined;
- typePrefixIfExists = !_.isUndefined(props.docsInfo.typeConfigs.typeNameToPrefix)
- ? props.docsInfo.typeConfigs.typeNameToPrefix[typeName as string]
- : undefined;
- sectionNameIfExists = !_.isUndefined(props.docsInfo.typeConfigs.typeNameToDocSection)
- ? props.docsInfo.typeConfigs.typeNameToDocSection[typeName as string]
- : undefined;
- }
+ 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 }}
- >
- {!_.isUndefined(typePrefixIfExists) ? `${typePrefixIfExists}.` : ''}
+ 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) &&
- (props.docsInfo.isPublicType(typeName as string) || !_.isUndefined(sectionNameIfExists))
+ ((props.typeDefinitionByName && props.typeDefinitionByName[typeName as string]) || isExportedClassReference)
) {
const id = Math.random().toString();
- const typeDefinitionAnchorId = _.isUndefined(sectionNameIfExists)
- ? `${props.sectionName}-${typeName}`
- : sectionNameIfExists;
- let typeDefinition;
- if (props.typeDefinitionByName) {
- typeDefinition = props.typeDefinitionByName[typeName as string];
- }
+ const typeDefinitionAnchorId = isExportedClassReference
+ ? props.type.name
+ : `${props.docsInfo.typeSectionName}-${typeName}`;
typeName = (
- <ScrollLink
- to={typeDefinitionAnchorId}
- offset={0}
- duration={sharedConstants.DOCS_SCROLL_DURATION_MS}
- containerId={sharedConstants.DOCS_CONTAINER_ID}
- >
- {_.isUndefined(typeDefinition) || sharedUtils.isUserOnMobile() ? (
- <span
- onClick={sharedUtils.setUrlHash.bind(null, typeDefinitionAnchorId)}
- style={{ color: colors.lightBlueA700, cursor: 'pointer' }}
- >
- {typeName}
- </span>
+ <span>
+ {sharedUtils.isUserOnMobile() || props.isInPopover || isExportedClassReference ? (
+ <span style={{ color: colors.lightBlueA700, cursor: 'pointer' }}>{typeName}</span>
) : (
- <span
- data-tip={true}
- data-for={id}
- onClick={sharedUtils.setUrlHash.bind(null, typeDefinitionAnchorId)}
- 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={typeDefinition}
- shouldAddId={false}
- docsInfo={props.docsInfo}
- />
- </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 (
@@ -230,4 +270,6 @@ export function Type(props: TypeProps): any {
)}
</span>
);
-}
+};
+
+Type.defaultProps = defaultProps;
diff --git a/packages/react-docs/src/components/type_definition.tsx b/packages/react-docs/src/components/type_definition.tsx
index c4bd7359a..a1fde51da 100644
--- a/packages/react-docs/src/components/type_definition.tsx
+++ b/packages/react-docs/src/components/type_definition.tsx
@@ -1,10 +1,11 @@
-import { AnchorTitle, colors, HeaderSizes } from '@0xproject/react-shared';
-import { errorUtils } from '@0xproject/utils';
+import { AnchorTitle, colors, HeaderSizes } from '@0x/react-shared';
+import { CustomType, CustomTypeChild, TypeDefinitionByName, TypeDocTypes } from '@0x/types';
+import { errorUtils } from '@0x/utils';
import * as _ from 'lodash';
import * as React from 'react';
import { DocsInfo } from '../docs_info';
-import { CustomType, CustomTypeChild, KindString, TypeDocTypes } from '../types';
+import { KindString, SupportedDocJson } from '../types';
import { constants } from '../utils/constants';
import { Comment } from './comment';
@@ -19,6 +20,8 @@ export interface TypeDefinitionProps {
customType: CustomType;
shouldAddId?: boolean;
docsInfo: DocsInfo;
+ typeDefinitionByName?: TypeDefinitionByName;
+ isInPopover?: boolean;
}
export interface TypeDefinitionState {
@@ -28,6 +31,7 @@ export interface TypeDefinitionState {
export class TypeDefinition extends React.Component<TypeDefinitionProps, TypeDefinitionState> {
public static defaultProps: Partial<TypeDefinitionProps> = {
shouldAddId: true,
+ isInPopover: false,
};
constructor(props: TypeDefinitionProps) {
super(props);
@@ -37,17 +41,20 @@ export class TypeDefinition extends React.Component<TypeDefinitionProps, TypeDef
}
public render(): React.ReactNode {
const customType = this.props.customType;
- if (!this.props.docsInfo.isPublicType(customType.name)) {
- return null; // no-op
- }
let typePrefix: string;
let codeSnippet: React.ReactNode;
switch (customType.kindString) {
case KindString.Interface:
- typePrefix = 'Interface';
+ typePrefix = this.props.docsInfo.type === SupportedDocJson.SolDoc ? 'Struct' : 'Interface';
codeSnippet = (
- <Interface type={customType} sectionName={this.props.sectionName} docsInfo={this.props.docsInfo} />
+ <Interface
+ type={customType}
+ sectionName={this.props.sectionName}
+ docsInfo={this.props.docsInfo}
+ typeDefinitionByName={this.props.typeDefinitionByName}
+ isInPopover={this.props.isInPopover}
+ />
);
break;
@@ -77,6 +84,8 @@ export class TypeDefinition extends React.Component<TypeDefinitionProps, TypeDef
type={customType.type}
sectionName={this.props.sectionName}
docsInfo={this.props.docsInfo}
+ typeDefinitionByName={this.props.typeDefinitionByName}
+ isInPopover={this.props.isInPopover}
/>
) : (
<Signature
@@ -89,6 +98,8 @@ export class TypeDefinition extends React.Component<TypeDefinitionProps, TypeDef
shouldHideMethodName={true}
shouldUseArrowSyntax={true}
docsInfo={this.props.docsInfo}
+ typeDefinitionByName={this.props.typeDefinitionByName}
+ isInPopover={this.props.isInPopover}
/>
)}
</span>
@@ -103,7 +114,7 @@ export class TypeDefinition extends React.Component<TypeDefinitionProps, TypeDef
return (
<div
id={this.props.shouldAddId ? typeDefinitionAnchorId : ''}
- className="pb2"
+ className="pb2 pt2"
style={{ overflow: 'hidden', width: '100%' }}
onMouseOver={this._setAnchorVisibility.bind(this, true)}
onMouseOut={this._setAnchorVisibility.bind(this, false)}
@@ -113,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 b37942da6..54b59ef1f 100644
--- a/packages/react-docs/src/docs_info.ts
+++ b/packages/react-docs/src/docs_info.ts
@@ -1,82 +1,64 @@
-import { MenuSubsectionsBySection } from '@0xproject/react-shared';
-import compareVersions = require('compare-versions');
+import { ALink, utils as sharedUtils } from '@0x/react-shared';
+import { DocAgnosticFormat, ObjectMap, TypeDefinitionByName } from '@0x/types';
import * as _ from 'lodash';
import {
ContractsByVersionByNetworkId,
- DocAgnosticFormat,
DocsInfoConfig,
- DocsInfoTypeConfigs,
DocsMenu,
- DoxityDocObj,
SectionNameToMarkdownByVersion,
SectionsMap,
SupportedDocJson,
- TypeDefinitionByName,
- TypeDocNode,
} from './types';
-import { doxityUtils } from './utils/doxity_utils';
-import { typeDocUtils } from './utils/typedoc_utils';
export class DocsInfo {
public id: string;
public type: SupportedDocJson;
public displayName: string;
+ public packageName: string;
public packageUrl: string;
- public menu: DocsMenu;
+ public markdownMenu: DocsMenu;
+ public typeSectionName: string;
public sections: SectionsMap;
public sectionNameToMarkdownByVersion: SectionNameToMarkdownByVersion;
public contractsByVersionByNetworkId?: ContractsByVersionByNetworkId;
- public typeConfigs: DocsInfoTypeConfigs;
- private readonly _docsInfo: DocsInfoConfig;
constructor(config: DocsInfoConfig) {
this.id = config.id;
this.type = config.type;
+ this.markdownMenu = config.markdownMenu;
this.displayName = config.displayName;
+ this.packageName = config.packageName;
this.packageUrl = config.packageUrl;
- this.sections = config.sections;
+ this.typeSectionName = config.type === SupportedDocJson.SolDoc ? 'structs' : 'types';
+ this.sections = config.markdownSections;
this.sectionNameToMarkdownByVersion = config.sectionNameToMarkdownByVersion;
this.contractsByVersionByNetworkId = config.contractsByVersionByNetworkId;
- this.typeConfigs = config.typeConfigs;
- this._docsInfo = config;
}
- public isPublicType(typeName: string): boolean {
- if (_.isUndefined(this._docsInfo.typeConfigs.publicTypes)) {
- return false;
- }
- const isPublic = _.includes(this._docsInfo.typeConfigs.publicTypes, typeName);
- return isPublic;
- }
- public getModulePathsIfExists(sectionName: string): string[] {
- const modulePathsIfExists = this._docsInfo.sectionNameToModulePath[sectionName];
- return modulePathsIfExists;
- }
- public getMenu(selectedVersion?: string): { [section: string]: string[] } {
- if (_.isUndefined(selectedVersion) || _.isUndefined(this._docsInfo.menuSubsectionToVersionWhenIntroduced)) {
- return this._docsInfo.menu;
- }
-
- const finalMenu = _.cloneDeep(this._docsInfo.menu);
- if (_.isUndefined(finalMenu.contracts)) {
- return finalMenu;
+ public getTypeDefinitionsByName(docAgnosticFormat: DocAgnosticFormat): ObjectMap<TypeDefinitionByName> {
+ if (_.isUndefined(docAgnosticFormat[this.typeSectionName])) {
+ return {};
}
- // TODO: refactor to include more sections then simply the `contracts` section
- finalMenu.contracts = _.filter(finalMenu.contracts, (contractName: string) => {
- const versionIntroducedIfExists = this._docsInfo.menuSubsectionToVersionWhenIntroduced[contractName];
- if (!_.isUndefined(versionIntroducedIfExists)) {
- const doesExistInSelectedVersion = compareVersions(selectedVersion, versionIntroducedIfExists) >= 0;
- return doesExistInSelectedVersion;
- } else {
- return true;
- }
- });
- return finalMenu;
+ const section = docAgnosticFormat[this.typeSectionName];
+ const typeDefinitionByName = _.keyBy(section.types, 'name') as any;
+ return typeDefinitionByName;
}
- public getMenuSubsectionsBySection(docAgnosticFormat?: DocAgnosticFormat): MenuSubsectionsBySection {
- const menuSubsectionsBySection = {} as MenuSubsectionsBySection;
+ 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);
@@ -86,43 +68,50 @@ export class DocsInfo {
return; // no-op
}
- if (!_.isUndefined(this.sections.types) && sectionName === this.sections.types) {
+ const isExportedFunctionSection =
+ docSection.functions.length === 1 &&
+ _.isEmpty(docSection.types) &&
+ _.isEmpty(docSection.methods) &&
+ _.isEmpty(docSection.constructors) &&
+ _.isEmpty(docSection.properties) &&
+ _.isEmpty(docSection.events);
+
+ 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 {
let eventNames: string[] = [];
if (!_.isUndefined(docSection.events)) {
const sortedEventNames = _.sortBy(docSection.events, 'name');
eventNames = _.map(sortedEventNames, m => m.name);
}
- const sortedMethodNames = _.sortBy(docSection.methods, 'name');
- const methodNames = _.map(sortedMethodNames, m => m.name);
- menuSubsectionsBySection[sectionName] = [...methodNames, ...eventNames];
+ const propertiesSortedByName = _.sortBy(docSection.properties, 'name');
+ const propertyNames = _.map(propertiesSortedByName, m => m.name);
+ const methodsSortedByName = _.sortBy(docSection.methods, 'name');
+ const methodNames = _.map(methodsSortedByName, m => m.name);
const sortedFunctionNames = _.sortBy(docSection.functions, 'name');
const functionNames = _.map(sortedFunctionNames, m => m.name);
- menuSubsectionsBySection[sectionName] = [...eventNames, ...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(this.sections.types)) {
- return {};
- }
-
- const typeDocSection = docAgnosticFormat[this.sections.types];
- const typeDefinitionByName = _.keyBy(typeDocSection.types, 'name') as any;
- return typeDefinitionByName;
- }
- public isVisibleConstructor(sectionName: string): boolean {
- return _.includes(this._docsInfo.visibleConstructors, sectionName);
- }
- public convertToDocAgnosticFormat(docObj: DoxityDocObj | TypeDocNode): DocAgnosticFormat {
- if (this.type === SupportedDocJson.Doxity) {
- return doxityUtils.convertToDocAgnosticFormat(docObj as DoxityDocObj);
- } else {
- return typeDocUtils.convertToDocAgnosticFormat(docObj as TypeDocNode, this);
- }
+ return sectionNameToLinks;
}
}
diff --git a/packages/react-docs/src/index.ts b/packages/react-docs/src/index.ts
index 30f5011b7..a5ed788b1 100644
--- a/packages/react-docs/src/index.ts
+++ b/packages/react-docs/src/index.ts
@@ -1,9 +1,11 @@
+export { DocAgnosticFormat, GeneratedDocJson } from '@0x/types';
+
// Exported to give users of this library added flexibility if they want to build
// a docs page from scratch using the individual components.
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';
@@ -12,9 +14,10 @@ export { Signature } from './components/signature';
export { SourceLink } from './components/source_link';
export { TypeDefinition } from './components/type_definition';
export { Type } from './components/type';
+export { TypeDocUtils } from './utils/typedoc_utils';
export { DocsInfo } from './docs_info';
-export { DocsInfoConfig, DocAgnosticFormat, DoxityDocObj, DocsMenu, SupportedDocJson, TypeDocNode } from './types';
+export { DocsInfoConfig, DocsMenu, SupportedDocJson } from './types';
export { constants } from './utils/constants';
diff --git a/packages/react-docs/src/monorepo_scripts/postpublish.ts b/packages/react-docs/src/monorepo_scripts/postpublish.ts
deleted file mode 100644
index dcb99d0f7..000000000
--- a/packages/react-docs/src/monorepo_scripts/postpublish.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-import { postpublishUtils } from '@0xproject/monorepo-scripts';
-
-import * as packageJSON from '../package.json';
-import * as tsConfigJSON from '../tsconfig.json';
-
-const cwd = `${__dirname}/..`;
-// tslint:disable-next-line:no-floating-promises
-postpublishUtils.runAsync(packageJSON, tsConfigJSON, cwd);
diff --git a/packages/react-docs/src/types.ts b/packages/react-docs/src/types.ts
index cbc774c2e..153448513 100644
--- a/packages/react-docs/src/types.ts
+++ b/packages/react-docs/src/types.ts
@@ -4,24 +4,14 @@ export interface SectionNameToMarkdownByVersion {
export interface DocsInfoConfig {
id: string;
+ packageName: string;
type: SupportedDocJson;
displayName: string;
packageUrl: string;
- menu: DocsMenu;
- sections: SectionsMap;
+ markdownMenu: DocsMenu;
+ markdownSections: SectionsMap;
sectionNameToMarkdownByVersion: SectionNameToMarkdownByVersion;
- visibleConstructors: string[];
- sectionNameToModulePath?: { [sectionName: string]: string[] };
- menuSubsectionToVersionWhenIntroduced?: { [sectionName: string]: string };
contractsByVersionByNetworkId?: ContractsByVersionByNetworkId;
- typeConfigs?: DocsInfoTypeConfigs;
-}
-
-export interface DocsInfoTypeConfigs {
- typeNameToExternalLink?: { [typeName: string]: string };
- publicTypes?: string[];
- typeNameToPrefix?: { [typeName: string]: string };
- typeNameToDocSection?: { [typeName: string]: string };
}
export interface DocsMenu {
@@ -32,64 +22,6 @@ export interface SectionsMap {
[sectionName: string]: string;
}
-export interface TypeDocType {
- type: TypeDocTypes;
- value: string;
- name: string;
- types: TypeDocType[];
- typeArguments?: TypeDocType[];
- declaration: TypeDocNode;
- elementType?: TypeDocType;
-}
-
-export interface TypeDocFlags {
- isStatic?: boolean;
- isOptional?: boolean;
- isPublic?: boolean;
- isExported?: boolean;
-}
-
-export interface TypeDocGroup {
- title: string;
- children: number[];
-}
-
-export interface TypeDocNode {
- id?: number;
- name?: string;
- kind?: string;
- defaultValue?: string;
- kindString?: string;
- type?: TypeDocType;
- fileName?: string;
- line?: number;
- comment?: TypeDocNode;
- text?: string;
- shortText?: string;
- returns?: string;
- declaration: TypeDocNode;
- flags?: TypeDocFlags;
- indexSignature?: TypeDocNode | TypeDocNode[]; // TypeDocNode in TypeDoc <V0.9.0, TypeDocNode[] in >V0.9.0
- signatures?: TypeDocNode[];
- parameters?: TypeDocNode[];
- typeParameter?: TypeDocNode[];
- sources?: TypeDocNode[];
- children?: TypeDocNode[];
- groups?: TypeDocGroup[];
-}
-
-export enum TypeDocTypes {
- Intrinsic = 'intrinsic',
- Reference = 'reference',
- Array = 'array',
- StringLiteral = 'stringLiteral',
- Reflection = 'reflection',
- Union = 'union',
- TypeParameter = 'typeParameter',
- Intersection = 'intersection',
- Unknown = 'unknown',
-}
-
// Exception: We don't make the values uppercase because these KindString's need to
// match up those returned by TypeDoc
export enum KindString {
@@ -105,134 +37,8 @@ export enum KindString {
Class = 'Class',
}
-export interface DocAgnosticFormat {
- [sectionName: string]: DocSection;
-}
-
-export interface DocSection {
- comment: string;
- constructors: Array<TypescriptMethod | SolidityMethod>;
- methods: Array<TypescriptMethod | SolidityMethod>;
- properties: Property[];
- types: CustomType[];
- functions?: TypescriptFunction[];
- events?: Event[];
-}
-
-export interface TypescriptMethod extends BaseMethod {
- source?: Source;
- isStatic?: boolean;
- typeParameter?: TypeParameter;
-}
-
-export interface TypescriptFunction extends BaseFunction {
- source?: Source;
- typeParameter?: TypeParameter;
-}
-
-export interface SolidityMethod extends BaseMethod {
- isConstant?: boolean;
- isPayable?: boolean;
-}
-
-export interface Source {
- fileName: string;
- line: number;
-}
-
-export interface Parameter {
- name: string;
- comment: string;
- isOptional: boolean;
- type: Type;
- defaultValue?: string;
-}
-
-export interface TypeParameter {
- name: string;
- type: Type;
-}
-
-export interface Type {
- name: string;
- typeDocType: TypeDocTypes;
- value?: string;
- typeArguments?: Type[];
- elementType?: ElementType;
- types?: Type[];
- method?: TypescriptMethod;
-}
-
-export interface ElementType {
- name: string;
- typeDocType: TypeDocTypes;
-}
-
-export interface IndexSignature {
- keyName: string;
- keyType: Type;
- valueName: string;
-}
-
-export interface CustomType {
- name: string;
- kindString: string;
- type?: Type;
- method?: TypescriptMethod;
- indexSignature?: IndexSignature;
- defaultValue?: string;
- comment?: string;
- children?: CustomTypeChild[];
-}
-
-export interface CustomTypeChild {
- name: string;
- type?: Type;
- defaultValue?: string;
-}
-
-export interface Event {
- name: string;
- eventArgs: EventArg[];
-}
-
-export interface EventArg {
- isIndexed: boolean;
- name: string;
- type: Type;
-}
-
-export interface Property {
- name: string;
- type: Type;
- source?: Source;
- comment?: string;
-}
-
-export interface BaseMethod {
- isConstructor: boolean;
- name: string;
- returnComment?: string | undefined;
- callPath: string;
- parameters: Parameter[];
- returnType: Type;
- comment?: string;
-}
-
-export interface BaseFunction {
- name: string;
- returnComment?: string | undefined;
- parameters: Parameter[];
- returnType: Type;
- comment?: string;
-}
-
-export interface TypeDefinitionByName {
- [typeName: string]: CustomType;
-}
-
export enum SupportedDocJson {
- Doxity = 'DOXITY',
+ SolDoc = 'SOL_DOC',
TypeDoc = 'TYPEDOC',
}
@@ -244,40 +50,6 @@ export interface ContractsByVersionByNetworkId {
};
}
-export interface DoxityDocObj {
- [contractName: string]: DoxityContractObj;
-}
-
-export interface DoxityContractObj {
- title: string;
- fileName: string;
- name: string;
- abiDocs: DoxityAbiDoc[];
-}
-
-export interface DoxityAbiDoc {
- constant: boolean;
- inputs: DoxityInput[];
- name: string;
- outputs: DoxityOutput[];
- payable: boolean;
- type: string;
- details?: string;
- return?: string;
-}
-
-export interface DoxityOutput {
- name: string;
- type: string;
-}
-
-export interface DoxityInput {
- name: string;
- type: string;
- description: string;
- indexed?: boolean;
-}
-
export interface AddressByContractName {
[contractName: string]: string;
}
diff --git a/packages/react-docs/src/utils/constants.ts b/packages/react-docs/src/utils/constants.ts
index c3c74fd11..b5b6cc00d 100644
--- a/packages/react-docs/src/utils/constants.ts
+++ b/packages/react-docs/src/utils/constants.ts
@@ -2,8 +2,9 @@ import { SupportedDocJson } from '../types';
export const constants = {
TYPES_SECTION_NAME: 'types',
+ EXTERNAL_EXPORTS_SECTION_NAME: 'external exports',
TYPE_TO_SYNTAX: {
- [SupportedDocJson.Doxity]: 'solidity',
+ [SupportedDocJson.SolDoc]: 'solidity',
[SupportedDocJson.TypeDoc]: 'typescript',
} as { [supportedDocType: string]: string },
};
diff --git a/packages/react-docs/src/utils/doxity_utils.ts b/packages/react-docs/src/utils/doxity_utils.ts
deleted file mode 100644
index 6815daa0c..000000000
--- a/packages/react-docs/src/utils/doxity_utils.ts
+++ /dev/null
@@ -1,176 +0,0 @@
-import * as _ from 'lodash';
-
-import {
- AbiTypes,
- DocAgnosticFormat,
- DocSection,
- DoxityAbiDoc,
- DoxityContractObj,
- DoxityDocObj,
- DoxityInput,
- EventArg,
- Parameter,
- Property,
- SolidityMethod,
- Type,
- TypeDocTypes,
-} from '../types';
-
-export const doxityUtils = {
- convertToDocAgnosticFormat(doxityDocObj: DoxityDocObj): DocAgnosticFormat {
- const docAgnosticFormat: DocAgnosticFormat = {};
- _.each(doxityDocObj, (doxityContractObj: DoxityContractObj, contractName: string) => {
- const doxityConstructor = _.find(doxityContractObj.abiDocs, (abiDoc: DoxityAbiDoc) => {
- return abiDoc.type === AbiTypes.Constructor;
- });
- const constructors = [];
- if (!_.isUndefined(doxityConstructor)) {
- const constructor = {
- isConstructor: true,
- name: doxityContractObj.name,
- comment: doxityConstructor.details,
- returnComment: doxityConstructor.return,
- callPath: '',
- parameters: doxityUtils._convertParameters(doxityConstructor.inputs),
- returnType: doxityUtils._convertType(doxityContractObj.name),
- };
- constructors.push(constructor);
- }
-
- const doxityMethods: DoxityAbiDoc[] = _.filter<DoxityAbiDoc>(
- doxityContractObj.abiDocs,
- (abiDoc: DoxityAbiDoc) => {
- return doxityUtils._isMethod(abiDoc);
- },
- );
- const methods: SolidityMethod[] = _.map<DoxityAbiDoc, SolidityMethod>(
- doxityMethods,
- (doxityMethod: DoxityAbiDoc) => {
- const outputs = !_.isUndefined(doxityMethod.outputs) ? doxityMethod.outputs : [];
- let returnTypeIfExists: Type;
- if (outputs.length === 0) {
- // no-op. It's already undefined
- } else if (outputs.length === 1) {
- const outputsType = outputs[0].type;
- returnTypeIfExists = doxityUtils._convertType(outputsType);
- } else {
- const outputsType = `[${_.map(outputs, output => output.type).join(', ')}]`;
- returnTypeIfExists = doxityUtils._convertType(outputsType);
- }
- // For ZRXToken, we want to convert it to zrxToken, rather then simply zRXToken
- const callPath =
- contractName !== 'ZRXToken'
- ? `${contractName[0].toLowerCase()}${contractName.slice(1)}.`
- : `${contractName.slice(0, 3).toLowerCase()}${contractName.slice(3)}.`;
- const method = {
- isConstructor: false,
- isConstant: doxityMethod.constant,
- isPayable: doxityMethod.payable,
- name: doxityMethod.name,
- comment: doxityMethod.details,
- returnComment: doxityMethod.return,
- callPath,
- parameters: doxityUtils._convertParameters(doxityMethod.inputs),
- returnType: returnTypeIfExists,
- };
- return method;
- },
- );
-
- const doxityProperties: DoxityAbiDoc[] = _.filter<DoxityAbiDoc>(
- doxityContractObj.abiDocs,
- (abiDoc: DoxityAbiDoc) => {
- return doxityUtils._isProperty(abiDoc);
- },
- );
- const properties = _.map<DoxityAbiDoc, Property>(doxityProperties, (doxityProperty: DoxityAbiDoc) => {
- // We assume that none of our functions return more then a single return value
- let typeName = doxityProperty.outputs[0].type;
- if (!_.isEmpty(doxityProperty.inputs)) {
- // Properties never have more then a single input
- typeName = `(${doxityProperty.inputs[0].type} => ${typeName})`;
- }
- const property = {
- name: doxityProperty.name,
- type: doxityUtils._convertType(typeName),
- comment: doxityProperty.details,
- };
- return property;
- });
-
- const doxityEvents = _.filter(
- doxityContractObj.abiDocs,
- (abiDoc: DoxityAbiDoc) => abiDoc.type === AbiTypes.Event,
- );
- const events = _.map(doxityEvents, doxityEvent => {
- const event = {
- name: doxityEvent.name,
- eventArgs: doxityUtils._convertEventArgs(doxityEvent.inputs),
- };
- return event;
- });
-
- const docSection: DocSection = {
- comment: doxityContractObj.title,
- constructors,
- methods,
- properties,
- types: [],
- functions: [],
- events,
- };
- docAgnosticFormat[contractName] = docSection;
- });
- return docAgnosticFormat;
- },
- _convertParameters(inputs: DoxityInput[]): Parameter[] {
- const parameters = _.map(inputs, input => {
- const parameter = {
- name: input.name,
- comment: input.description,
- isOptional: false,
- type: doxityUtils._convertType(input.type),
- };
- return parameter;
- });
- return parameters;
- },
- _convertType(typeName: string): Type {
- const type = {
- name: typeName,
- typeDocType: TypeDocTypes.Intrinsic,
- };
- return type;
- },
- _isMethod(abiDoc: DoxityAbiDoc): boolean {
- if (abiDoc.type !== AbiTypes.Function) {
- return false;
- }
- const hasInputs = !_.isEmpty(abiDoc.inputs);
- const hasNamedOutputIfExists = !hasInputs || !_.isEmpty(abiDoc.inputs[0].name);
- const isNameAllCaps = abiDoc.name === abiDoc.name.toUpperCase();
- const isMethod = hasNamedOutputIfExists && !isNameAllCaps;
- return isMethod;
- },
- _isProperty(abiDoc: DoxityAbiDoc): boolean {
- if (abiDoc.type !== AbiTypes.Function) {
- return false;
- }
- const hasInputs = !_.isEmpty(abiDoc.inputs);
- const hasNamedOutputIfExists = !hasInputs || !_.isEmpty(abiDoc.inputs[0].name);
- const isNameAllCaps = abiDoc.name === abiDoc.name.toUpperCase();
- const isProperty = !hasNamedOutputIfExists || isNameAllCaps;
- return isProperty;
- },
- _convertEventArgs(inputs: DoxityInput[]): EventArg[] {
- const eventArgs = _.map(inputs, input => {
- const eventArg = {
- isIndexed: input.indexed,
- name: input.name,
- type: doxityUtils._convertType(input.type),
- };
- return eventArg;
- });
- return eventArgs;
- },
-};
diff --git a/packages/react-docs/src/utils/typedoc_utils.ts b/packages/react-docs/src/utils/typedoc_utils.ts
index a6d938e94..f74ec3e28 100644
--- a/packages/react-docs/src/utils/typedoc_utils.ts
+++ b/packages/react-docs/src/utils/typedoc_utils.ts
@@ -1,17 +1,14 @@
-import { errorUtils } from '@0xproject/utils';
-import * as _ from 'lodash';
-
-import { DocsInfo } from '../docs_info';
import {
CustomType,
CustomTypeChild,
DocAgnosticFormat,
DocSection,
+ ExternalExportToLink,
+ ExternalTypeToLink,
+ GeneratedDocJson,
IndexSignature,
- KindString,
Parameter,
Property,
- SectionsMap,
Type,
TypeDocNode,
TypeDocType,
@@ -19,10 +16,48 @@ import {
TypeParameter,
TypescriptFunction,
TypescriptMethod,
-} from '../types';
+} from '@0x/types';
+import { errorUtils } from '@0x/utils';
+import * as _ from 'lodash';
+
+import { DocsInfo } from '../docs_info';
+import { KindString } from '../types';
+
+import { constants } from './constants';
+
+export class TypeDocUtils {
+ private readonly _typeDocNameOrder: string[];
+ private readonly _externalTypeToLink: ExternalTypeToLink;
+ private readonly _externalExportToLink: ExternalExportToLink;
+ private readonly _docsInfo: DocsInfo;
+ private readonly _typeDocJson: TypeDocNode;
+ private readonly _classNames: string[];
+ constructor(generatedDocJson: GeneratedDocJson, docsInfo: DocsInfo) {
+ this._docsInfo = docsInfo;
+ const exportPathOrder = generatedDocJson.metadata.exportPathOrder;
+ const exportPathToTypedocNames = generatedDocJson.metadata.exportPathToTypedocNames;
+ this._externalTypeToLink = generatedDocJson.metadata.externalTypeToLink;
+ this._externalExportToLink = generatedDocJson.metadata.externalExportToLink;
+ this._typeDocJson = generatedDocJson.typedocJson;
+
+ this._typeDocNameOrder = _.compact(
+ _.flatten(
+ _.map(exportPathOrder, exportPath => {
+ return exportPathToTypedocNames[exportPath];
+ }),
+ ),
+ );
-export const typeDocUtils = {
- isType(entity: TypeDocNode): boolean {
+ this._classNames = [];
+ _.each(this._typeDocJson.children, file => {
+ _.each(file.children, child => {
+ if (child.kindString === KindString.Class) {
+ this._classNames.push(child.name);
+ }
+ });
+ });
+ }
+ public isType(entity: TypeDocNode): boolean {
return (
entity.kindString === KindString.Interface ||
entity.kindString === KindString.Function ||
@@ -30,20 +65,20 @@ export const typeDocUtils = {
entity.kindString === KindString.Variable ||
entity.kindString === KindString.Enumeration
);
- },
- isMethod(entity: TypeDocNode): boolean {
+ }
+ public isMethod(entity: TypeDocNode): boolean {
return entity.kindString === KindString.Method;
- },
- isConstructor(entity: TypeDocNode): boolean {
+ }
+ public isConstructor(entity: TypeDocNode): boolean {
return entity.kindString === KindString.Constructor;
- },
- isProperty(entity: TypeDocNode): boolean {
+ }
+ public isProperty(entity: TypeDocNode): boolean {
return entity.kindString === KindString.Property;
- },
- isPrivateOrProtectedProperty(propertyName: string): boolean {
- return _.startsWith(propertyName, '_');
- },
- getModuleDefinitionsBySectionName(versionDocObj: TypeDocNode, configModulePaths: string[]): TypeDocNode[] {
+ }
+ public isUnderscorePrefixed(name: string): boolean {
+ return _.startsWith(name, '_');
+ }
+ public getModuleDefinitionsBySectionName(versionDocObj: TypeDocNode, configModulePaths: string[]): TypeDocNode[] {
const moduleDefinitions: TypeDocNode[] = [];
const jsonModules = versionDocObj.children;
_.each(jsonModules, jsonMod => {
@@ -54,66 +89,89 @@ export const typeDocUtils = {
});
});
return moduleDefinitions;
- },
- convertToDocAgnosticFormat(typeDocJson: TypeDocNode, docsInfo: DocsInfo): DocAgnosticFormat {
- const subMenus = _.values(docsInfo.getMenu());
- const orderedSectionNames = _.flatten(subMenus);
+ }
+ public convertToDocAgnosticFormat(): DocAgnosticFormat {
const docAgnosticFormat: DocAgnosticFormat = {};
- _.each(orderedSectionNames, sectionName => {
- const modulePathsIfExists = docsInfo.getModulePathsIfExists(sectionName);
- if (_.isUndefined(modulePathsIfExists)) {
- return; // no-op
- }
- const packageDefinitions = typeDocUtils.getModuleDefinitionsBySectionName(typeDocJson, modulePathsIfExists);
- let packageDefinitionWithMergedChildren;
- if (_.isEmpty(packageDefinitions)) {
- return; // no-op
- } else if (packageDefinitions.length === 1) {
- packageDefinitionWithMergedChildren = packageDefinitions[0];
- } else {
- // HACK: For now, if there are two modules to display in a single section,
- // we simply concat the children. This works for our limited use-case where
- // we want to display types stored in two files under a single section
- packageDefinitionWithMergedChildren = packageDefinitions[0];
- for (let i = 1; i < packageDefinitions.length; i++) {
- packageDefinitionWithMergedChildren.children = [
- ...packageDefinitionWithMergedChildren.children,
- ...packageDefinitions[i].children,
- ];
- }
- }
- let entities;
- let packageComment = '';
- // HACK: We assume 1 exported class per file
- const classChildren = _.filter(packageDefinitionWithMergedChildren.children, (child: TypeDocNode) => {
- return child.kindString === KindString.Class;
- });
- if (classChildren.length > 1 && sectionName !== 'types') {
- throw new Error('`react-docs` only supports projects with 1 exported class per file');
- }
- const isClassExport = packageDefinitionWithMergedChildren.children[0].kindString === KindString.Class;
- const isObjectLiteralExport =
- packageDefinitionWithMergedChildren.children[0].kindString === KindString.ObjectLiteral;
- if (isClassExport) {
- entities = packageDefinitionWithMergedChildren.children[0].children;
- const commentObj = packageDefinitionWithMergedChildren.children[0].comment;
- packageComment = !_.isUndefined(commentObj) ? commentObj.shortText : packageComment;
- } else if (isObjectLiteralExport) {
- entities = packageDefinitionWithMergedChildren.children[0].children;
- const commentObj = packageDefinitionWithMergedChildren.children[0].comment;
- packageComment = !_.isUndefined(commentObj) ? commentObj.shortText : packageComment;
- } else {
- entities = packageDefinitionWithMergedChildren.children;
- }
+ if (!_.isEmpty(this._externalExportToLink)) {
+ this._docsInfo.sections[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: [],
+ methods: [],
+ functions: [],
+ properties: [],
+ types: [],
+ externalExportToLink: this._externalExportToLink,
+ };
+ docAgnosticFormat[constants.EXTERNAL_EXPORTS_SECTION_NAME] = docSection;
+ }
- const docSection = typeDocUtils._convertEntitiesToDocSection(entities, docsInfo, sectionName);
- docSection.comment = packageComment;
- docAgnosticFormat[sectionName] = docSection;
+ const typeEntities: TypeDocNode[] = [];
+ _.each(this._typeDocNameOrder, typeDocName => {
+ const fileChildIndex = _.findIndex(this._typeDocJson.children, child => child.name === typeDocName);
+ const fileChild = this._typeDocJson.children[fileChildIndex];
+ let sectionName: string;
+ _.each(fileChild.children, child => {
+ switch (child.kindString) {
+ case KindString.Class:
+ case KindString.ObjectLiteral: {
+ sectionName = child.name;
+ this._docsInfo.sections[sectionName] = sectionName;
+ this._docsInfo.markdownMenu[sectionName] = [sectionName];
+ const entities = child.children;
+ const commentObj = child.comment;
+ const sectionComment = !_.isUndefined(commentObj) ? commentObj.shortText : '';
+ const isClassOrObjectLiteral = true;
+ const docSection = this._convertEntitiesToDocSection(
+ entities,
+ sectionName,
+ isClassOrObjectLiteral,
+ );
+ docSection.comment = sectionComment;
+ docAgnosticFormat[sectionName] = docSection;
+ break;
+ }
+ case KindString.Function: {
+ sectionName = child.name;
+ this._docsInfo.sections[sectionName] = sectionName;
+ this._docsInfo.markdownMenu[sectionName] = [sectionName];
+ const entities = [child];
+ const commentObj = child.comment;
+ const SectionComment = !_.isUndefined(commentObj) ? commentObj.shortText : '';
+ const docSection = this._convertEntitiesToDocSection(entities, sectionName);
+ docSection.comment = SectionComment;
+ docAgnosticFormat[sectionName] = docSection;
+ break;
+ }
+ case KindString.Interface:
+ case KindString.Variable:
+ case KindString.Enumeration:
+ case KindString.TypeAlias:
+ typeEntities.push(child);
+ break;
+ default:
+ throw errorUtils.spawnSwitchErr('kindString', child.kindString);
+ }
+ });
});
+ if (!_.isEmpty(typeEntities)) {
+ this._docsInfo.sections[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;
+ }
+
return docAgnosticFormat;
- },
- _convertEntitiesToDocSection(entities: TypeDocNode[], docsInfo: DocsInfo, sectionName: string): DocSection {
+ }
+ private _convertEntitiesToDocSection(
+ entities: TypeDocNode[],
+ sectionName: string,
+ isClassOrObjectLiteral: boolean = false,
+ ): DocSection {
const docSection: DocSection = {
comment: '',
constructors: [],
@@ -128,60 +186,44 @@ export const typeDocUtils = {
switch (entity.kindString) {
case KindString.Constructor:
isConstructor = true;
- const constructor = typeDocUtils._convertMethod(
- entity,
- isConstructor,
- docsInfo.sections,
- sectionName,
- docsInfo.id,
- );
+ const constructor = this._convertMethod(entity, isConstructor, sectionName);
docSection.constructors.push(constructor);
break;
case KindString.Function:
if (entity.flags.isExported) {
- const func = typeDocUtils._convertFunction(entity, docsInfo.sections, sectionName, docsInfo.id);
- docSection.functions.push(func);
+ const funcName = entity.signatures[0].name;
+ if (!this.isUnderscorePrefixed(funcName)) {
+ const func = this._convertFunction(entity, sectionName, isClassOrObjectLiteral);
+ docSection.functions.push(func);
+ }
}
break;
case KindString.Method:
- if (entity.flags.isPublic) {
+ if (entity.flags.isPublic && !this.isUnderscorePrefixed(entity.name)) {
isConstructor = false;
- const method = typeDocUtils._convertMethod(
- entity,
- isConstructor,
- docsInfo.sections,
- sectionName,
- docsInfo.id,
- );
+ const method = this._convertMethod(entity, isConstructor, sectionName);
docSection.methods.push(method);
}
break;
- case KindString.Property:
- if (!typeDocUtils.isPrivateOrProtectedProperty(entity.name)) {
- const property = typeDocUtils._convertProperty(
- entity,
- docsInfo.sections,
- sectionName,
- docsInfo.id,
- );
+ case KindString.Property: {
+ if (!this.isUnderscorePrefixed(entity.name)) {
+ const property = this._convertProperty(entity, sectionName);
docSection.properties.push(property);
}
break;
+ }
- case KindString.Interface:
case KindString.Variable:
- case KindString.Enumeration:
- case KindString.TypeAlias:
- if (docsInfo.isPublicType(entity.name)) {
- const customType = typeDocUtils._convertCustomType(
- entity,
- docsInfo.sections,
- sectionName,
- docsInfo.id,
- );
+ if (isClassOrObjectLiteral) {
+ // Render as a property
+ const property = this._convertProperty(entity, sectionName);
+ docSection.properties.push(property);
+ } else {
+ // Otherwise, render as a type
+ const customType = this._convertCustomType(entity, sectionName);
const seenTypeNames = _.map(docSection.types, t => t.name);
const isUnseen = !_.includes(seenTypeNames, customType.name);
if (isUnseen) {
@@ -190,6 +232,18 @@ export const typeDocUtils = {
}
break;
+ case KindString.Interface:
+ case KindString.Enumeration:
+ case KindString.TypeAlias: {
+ const customType = this._convertCustomType(entity, sectionName);
+ const seenTypeNames = _.map(docSection.types, t => t.name);
+ const isUnseen = !_.includes(seenTypeNames, customType.name);
+ if (isUnseen) {
+ docSection.types.push(customType);
+ }
+ break;
+ }
+
case KindString.Class:
// We currently do not support more then a single class per file
// except for the types section, where we ignore classes since we
@@ -201,25 +255,17 @@ export const typeDocUtils = {
}
});
return docSection;
- },
- _convertCustomType(entity: TypeDocNode, sections: SectionsMap, sectionName: string, docId: string): CustomType {
- const typeIfExists = !_.isUndefined(entity.type)
- ? typeDocUtils._convertType(entity.type, sections, sectionName, docId)
- : undefined;
+ }
+ private _convertCustomType(entity: TypeDocNode, sectionName: string): CustomType {
+ const typeIfExists = !_.isUndefined(entity.type) ? this._convertType(entity.type, sectionName) : undefined;
const isConstructor = false;
const methodIfExists = !_.isUndefined(entity.declaration)
- ? typeDocUtils._convertMethod(entity.declaration, isConstructor, sections, sectionName, docId)
+ ? this._convertMethod(entity.declaration, isConstructor, sectionName)
: undefined;
const doesIndexSignatureExist = !_.isUndefined(entity.indexSignature);
- const isIndexSignatureArray = _.isArray(entity.indexSignature);
- // HACK: TypeDoc Versions <0.9.0 indexSignature is of type TypeDocNode[]
- // Versions >0.9.0 have it as type TypeDocNode
- const indexSignature =
- doesIndexSignatureExist && isIndexSignatureArray
- ? (entity.indexSignature as TypeDocNode[])[0]
- : (entity.indexSignature as TypeDocNode);
+ const indexSignature = entity.indexSignature;
const indexSignatureIfExists = doesIndexSignatureExist
- ? typeDocUtils._convertIndexSignature(indexSignature, sections, sectionName, docId)
+ ? this._convertIndexSignature(indexSignature, sectionName)
: undefined;
const commentIfExists =
!_.isUndefined(entity.comment) && !_.isUndefined(entity.comment.shortText)
@@ -229,13 +275,13 @@ export const typeDocUtils = {
const childrenIfExist = !_.isUndefined(entity.children)
? _.map(entity.children, (child: TypeDocNode) => {
let childTypeIfExists = !_.isUndefined(child.type)
- ? typeDocUtils._convertType(child.type, sections, sectionName, docId)
+ ? this._convertType(child.type, sectionName)
: undefined;
if (child.kindString === KindString.Method) {
childTypeIfExists = {
name: child.name,
typeDocType: TypeDocTypes.Reflection,
- method: typeDocUtils._convertMethod(child, isConstructor, sections, sectionName, docId),
+ method: this._convertMethod(child, isConstructor, sectionName),
};
}
const c: CustomTypeChild = {
@@ -258,71 +304,49 @@ export const typeDocUtils = {
children: childrenIfExist,
};
return customType;
- },
- _convertIndexSignature(
- entity: TypeDocNode,
- sections: SectionsMap,
- sectionName: string,
- docId: string,
- ): IndexSignature {
+ }
+ private _convertIndexSignature(entity: TypeDocNode, sectionName: string): IndexSignature {
const key = entity.parameters[0];
const indexSignature = {
keyName: key.name,
- keyType: typeDocUtils._convertType(key.type, sections, sectionName, docId),
+ keyType: this._convertType(key.type, sectionName),
valueName: entity.type.name,
};
return indexSignature;
- },
- _convertProperty(entity: TypeDocNode, sections: SectionsMap, sectionName: string, docId: string): Property {
+ }
+ private _convertProperty(entity: TypeDocNode, sectionName: string): Property {
const source = entity.sources[0];
const commentIfExists = !_.isUndefined(entity.comment) ? entity.comment.shortText : undefined;
+ const isConstructor = false;
+ const isStatic = _.isUndefined(entity.flags.isStatic) ? false : entity.flags.isStatic;
+ const callPath = this._getCallPath(sectionName, isStatic, isConstructor, entity.name);
const property = {
name: entity.name,
- type: typeDocUtils._convertType(entity.type, sections, sectionName, docId),
+ type: this._convertType(entity.type, sectionName),
source: {
fileName: source.fileName,
line: source.line,
},
comment: commentIfExists,
+ callPath,
};
return property;
- },
- _convertMethod(
- entity: TypeDocNode,
- isConstructor: boolean,
- sections: SectionsMap,
- sectionName: string,
- docId: string,
- ): TypescriptMethod {
+ }
+ private _convertMethod(entity: TypeDocNode, isConstructor: boolean, sectionName: string): TypescriptMethod {
const signature = entity.signatures[0];
const source = entity.sources[0];
const hasComment = !_.isUndefined(signature.comment);
const isStatic = _.isUndefined(entity.flags.isStatic) ? false : entity.flags.isStatic;
- // HACK: we use the fact that the sectionName is the same as the property name at the top-level
- // of the public interface. In the future, we shouldn't use this hack but rather get it from the JSON.
- let callPath;
- if (isConstructor || entity.name === '__type') {
- callPath = '';
- // TODO: Get rid of this 0x-specific logic
- } else if (docId === 'ZERO_EX_JS') {
- const topLevelInterface = isStatic ? 'ZeroEx.' : 'zeroEx.';
- callPath =
- !_.isUndefined(sections.zeroEx) && sectionName !== sections.zeroEx
- ? `${topLevelInterface}${sectionName}.`
- : topLevelInterface;
- } else {
- callPath = `${sectionName}.`;
- }
-
const parameters = _.map(signature.parameters, param => {
- return typeDocUtils._convertParameter(param, sections, sectionName, docId);
+ return this._convertParameter(param, sectionName);
});
- const returnType = typeDocUtils._convertType(signature.type, sections, sectionName, docId);
+ const returnType = this._convertType(signature.type, sectionName);
const typeParameter = _.isUndefined(signature.typeParameter)
? undefined
- : typeDocUtils._convertTypeParameter(signature.typeParameter[0], sections, sectionName, docId);
+ : this._convertTypeParameter(signature.typeParameter[0], sectionName);
+ const callPath = this._getCallPath(sectionName, isStatic, isConstructor, entity.name);
const method = {
isConstructor,
isStatic,
@@ -332,6 +356,10 @@ export const typeDocUtils = {
source: {
fileName: source.fileName,
line: source.line,
+ callPath,
+ parameters,
+ returnType,
+ typeParameter,
},
callPath,
parameters,
@@ -339,29 +367,49 @@ export const typeDocUtils = {
typeParameter,
};
return method;
- },
- _convertFunction(
- entity: TypeDocNode,
- sections: SectionsMap,
- sectionName: string,
- docId: string,
- ): TypescriptFunction {
+ }
+ private _getCallPath(sectionName: string, isStatic: boolean, isConstructor: boolean, entityName: string): string {
+ // HACK: we use the fact that the sectionName is the same as the property name at the top-level
+ // of the public interface. In the future, we shouldn't use this hack but rather get it from the JSON.
+ let callPath;
+ if (isConstructor || entityName === '__type') {
+ callPath = '';
+ } else {
+ const prefix = isStatic ? sectionName : this._getLowercaseSectionName(sectionName);
+ callPath = `${prefix}.`;
+ }
+ return callPath;
+ }
+ private _getLowercaseSectionName(sectionName: string): string {
+ if (_.startsWith(sectionName, 'ERC')) {
+ return `${sectionName.slice(0, 3).toLowerCase()}${sectionName.slice(3)}`;
+ }
+ return `${sectionName[0].toLowerCase()}${sectionName.slice(1)}`;
+ }
+ private _convertFunction(entity: TypeDocNode, sectionName: string, isObjectLiteral: boolean): TypescriptFunction {
const signature = entity.signatures[0];
const source = entity.sources[0];
const hasComment = !_.isUndefined(signature.comment);
const parameters = _.map(signature.parameters, param => {
- return typeDocUtils._convertParameter(param, sections, sectionName, docId);
+ return this._convertParameter(param, sectionName);
});
- const returnType = typeDocUtils._convertType(signature.type, sections, sectionName, docId);
+ const returnType = this._convertType(signature.type, sectionName);
const typeParameter = _.isUndefined(signature.typeParameter)
? undefined
- : typeDocUtils._convertTypeParameter(signature.typeParameter[0], sections, sectionName, docId);
+ : this._convertTypeParameter(signature.typeParameter[0], sectionName);
+ let callPath = '';
+ if (isObjectLiteral) {
+ const isConstructor = false;
+ const isStatic = false;
+ callPath = this._getCallPath(sectionName, isStatic, isConstructor, entity.name);
+ }
const func = {
name: signature.name,
comment: hasComment ? signature.comment.shortText : undefined,
returnComment: hasComment && signature.comment.returns ? signature.comment.returns : undefined,
+ callPath,
source: {
fileName: source.fileName,
line: source.line,
@@ -371,21 +419,19 @@ export const typeDocUtils = {
typeParameter,
};
return func;
- },
- _convertTypeParameter(
- entity: TypeDocNode,
- sections: SectionsMap,
- sectionName: string,
- docId: string,
- ): TypeParameter {
- const type = typeDocUtils._convertType(entity.type, sections, sectionName, docId);
+ }
+ private _convertTypeParameter(entity: TypeDocNode, sectionName: string): TypeParameter {
+ let type;
+ if (!_.isUndefined(entity.type)) {
+ type = this._convertType(entity.type, sectionName);
+ }
const parameter = {
name: entity.name,
type,
};
return parameter;
- },
- _convertParameter(entity: TypeDocNode, sections: SectionsMap, sectionName: string, docId: string): Parameter {
+ }
+ private _convertParameter(entity: TypeDocNode, sectionName: string): Parameter {
let comment = '<No comment>';
if (entity.comment && entity.comment.shortText) {
comment = entity.comment.shortText;
@@ -395,7 +441,7 @@ export const typeDocUtils = {
const isOptional = !_.isUndefined(entity.flags.isOptional) ? entity.flags.isOptional : false;
- const type = typeDocUtils._convertType(entity.type, sections, sectionName, docId);
+ const type = this._convertType(entity.type, sectionName);
const parameter = {
name: entity.name,
@@ -405,19 +451,33 @@ export const typeDocUtils = {
type,
};
return parameter;
- },
- _convertType(entity: TypeDocType, sections: SectionsMap, sectionName: string, docId: string): Type {
+ }
+ private _convertType(entity: TypeDocType, sectionName: string): Type {
const typeArguments = _.map(entity.typeArguments, typeArgument => {
- return typeDocUtils._convertType(typeArgument, sections, sectionName, docId);
+ return this._convertType(typeArgument, sectionName);
});
const types = _.map(entity.types, t => {
- return typeDocUtils._convertType(t, sections, sectionName, docId);
+ return this._convertType(t, sectionName);
});
- const isConstructor = false;
- const methodIfExists = !_.isUndefined(entity.declaration)
- ? typeDocUtils._convertMethod(entity.declaration, isConstructor, sections, sectionName, docId)
- : undefined;
+ let indexSignatureIfExists;
+ let methodIfExists;
+ let tupleElementsIfExists;
+ const doesIndexSignatureExist =
+ !_.isUndefined(entity.declaration) && !_.isUndefined(entity.declaration.indexSignature);
+ if (doesIndexSignatureExist) {
+ const indexSignature = entity.declaration.indexSignature;
+ indexSignatureIfExists = this._convertIndexSignature(indexSignature, sectionName);
+ } else if (!_.isUndefined(entity.declaration)) {
+ const isConstructor = false;
+ methodIfExists = this._convertMethod(entity.declaration, isConstructor, sectionName);
+ } else if (entity.type === TypeDocTypes.Tuple) {
+ tupleElementsIfExists = _.map(entity.elements, el => {
+ // the following line is required due to an open tslint issue, https://github.com/palantir/tslint/issues/3540
+ // tslint:disable-next-line:no-unnecessary-type-assertion
+ return { name: el.name, typeDocType: el.type as TypeDocTypes };
+ });
+ }
const elementTypeIfExists = !_.isUndefined(entity.elementType)
? {
@@ -426,15 +486,22 @@ export const typeDocUtils = {
}
: undefined;
- const type = {
+ const type: Type = {
name: entity.name,
value: entity.value,
+ isExportedClassReference: _.includes(this._classNames, entity.name),
typeDocType: entity.type,
typeArguments,
elementType: elementTypeIfExists,
types,
method: methodIfExists,
+ indexSignature: indexSignatureIfExists,
+ tupleElements: tupleElementsIfExists,
};
+ const externalLinkIfExists = this._externalTypeToLink[entity.name];
+ if (!_.isUndefined(externalLinkIfExists)) {
+ type.externalLink = externalLinkIfExists;
+ }
return type;
- },
-};
+ }
+} // tslint:disable:max-file-line-count
diff --git a/packages/react-docs/tsconfig.json b/packages/react-docs/tsconfig.json
index 82f44a62c..76e2cd027 100644
--- a/packages/react-docs/tsconfig.json
+++ b/packages/react-docs/tsconfig.json
@@ -1,9 +1,10 @@
{
"extends": "../../tsconfig",
"compilerOptions": {
- "outDir": "./lib/",
+ "outDir": "lib",
+ "rootDir": "src",
"jsx": "react",
- "baseUrl": "./",
+ "baseUrl": ".",
"strictNullChecks": false,
"paths": {
"*": ["node_modules/@types/*", "*"]
diff --git a/packages/react-docs/tslint.json b/packages/react-docs/tslint.json
index c78434416..c3f6d9cae 100644
--- a/packages/react-docs/tslint.json
+++ b/packages/react-docs/tslint.json
@@ -1,5 +1,5 @@
{
- "extends": ["@0xproject/tslint-config"],
+ "extends": ["@0x/tslint-config"],
"rules": {
"no-object-literal-type-assertion": false,
"completed-docs": false,