aboutsummaryrefslogtreecommitdiffstats
path: root/packages/website/ts/pages
diff options
context:
space:
mode:
authorFabio Berger <me@fabioberger.com>2018-01-30 20:26:46 +0800
committerFabio Berger <me@fabioberger.com>2018-01-30 20:26:46 +0800
commitc6dece6bd1e5f5afa56b290557eb7a6245c76cb6 (patch)
treead7a33ffe5d80c0eb41ae10fbc8314f193e52383 /packages/website/ts/pages
parent93a5b3f457c1211676296840c285759007a55500 (diff)
downloaddexon-sol-tools-c6dece6bd1e5f5afa56b290557eb7a6245c76cb6.tar
dexon-sol-tools-c6dece6bd1e5f5afa56b290557eb7a6245c76cb6.tar.gz
dexon-sol-tools-c6dece6bd1e5f5afa56b290557eb7a6245c76cb6.tar.bz2
dexon-sol-tools-c6dece6bd1e5f5afa56b290557eb7a6245c76cb6.tar.lz
dexon-sol-tools-c6dece6bd1e5f5afa56b290557eb7a6245c76cb6.tar.xz
dexon-sol-tools-c6dece6bd1e5f5afa56b290557eb7a6245c76cb6.tar.zst
dexon-sol-tools-c6dece6bd1e5f5afa56b290557eb7a6245c76cb6.zip
Add config file specifically in prettier command and fix files
Diffstat (limited to 'packages/website/ts/pages')
-rw-r--r--packages/website/ts/pages/about/about.tsx416
-rw-r--r--packages/website/ts/pages/about/profile.tsx116
-rw-r--r--packages/website/ts/pages/documentation/comment.tsx16
-rw-r--r--packages/website/ts/pages/documentation/custom_enum.tsx34
-rw-r--r--packages/website/ts/pages/documentation/docs_info.ts198
-rw-r--r--packages/website/ts/pages/documentation/documentation.tsx648
-rw-r--r--packages/website/ts/pages/documentation/enum.tsx26
-rw-r--r--packages/website/ts/pages/documentation/event_definition.tsx132
-rw-r--r--packages/website/ts/pages/documentation/interface.tsx98
-rw-r--r--packages/website/ts/pages/documentation/method_block.tsx238
-rw-r--r--packages/website/ts/pages/documentation/method_signature.tsx148
-rw-r--r--packages/website/ts/pages/documentation/source_link.tsx38
-rw-r--r--packages/website/ts/pages/documentation/type.tsx354
-rw-r--r--packages/website/ts/pages/documentation/type_definition.tsx194
-rw-r--r--packages/website/ts/pages/faq/faq.tsx846
-rw-r--r--packages/website/ts/pages/faq/question.tsx76
-rw-r--r--packages/website/ts/pages/landing/landing.tsx1420
-rw-r--r--packages/website/ts/pages/not_found.tsx52
-rw-r--r--packages/website/ts/pages/shared/anchor_title.tsx142
-rw-r--r--packages/website/ts/pages/shared/markdown_code_block.tsx28
-rw-r--r--packages/website/ts/pages/shared/markdown_section.tsx112
-rw-r--r--packages/website/ts/pages/shared/nested_sidebar_menu.tsx268
-rw-r--r--packages/website/ts/pages/shared/section_header.tsx72
-rw-r--r--packages/website/ts/pages/shared/version_drop_down.tsx50
-rw-r--r--packages/website/ts/pages/wiki/wiki.tsx344
25 files changed, 3033 insertions, 3033 deletions
diff --git a/packages/website/ts/pages/about/about.tsx b/packages/website/ts/pages/about/about.tsx
index 411456427..c929673f5 100644
--- a/packages/website/ts/pages/about/about.tsx
+++ b/packages/website/ts/pages/about/about.tsx
@@ -10,239 +10,239 @@ import { constants } from 'ts/utils/constants';
import { utils } from 'ts/utils/utils';
const teamRow1: ProfileInfo[] = [
- {
- name: 'Will Warren',
- title: 'Co-founder & CEO',
- description: `Smart contract R&D. Previously applied physics at Los Alamos \
+ {
+ name: 'Will Warren',
+ title: 'Co-founder & CEO',
+ description: `Smart contract R&D. Previously applied physics at Los Alamos \
Nat Lab. Mechanical engineering at UC San Diego. PhD dropout.`,
- image: '/images/team/will.jpg',
- linkedIn: 'https://www.linkedin.com/in/will-warren-92aab62b/',
- github: 'https://github.com/willwarren89',
- medium: 'https://medium.com/@willwarren89',
- },
- {
- name: 'Amir Bandeali',
- title: 'Co-founder & CTO',
- description: `Smart contract R&D. Previously fixed income trader at DRW. \
+ image: '/images/team/will.jpg',
+ linkedIn: 'https://www.linkedin.com/in/will-warren-92aab62b/',
+ github: 'https://github.com/willwarren89',
+ medium: 'https://medium.com/@willwarren89',
+ },
+ {
+ name: 'Amir Bandeali',
+ title: 'Co-founder & CTO',
+ description: `Smart contract R&D. Previously fixed income trader at DRW. \
Finance at University of Illinois, Urbana-Champaign.`,
- image: '/images/team/amir.jpeg',
- linkedIn: 'https://www.linkedin.com/in/abandeali1/',
- github: 'https://github.com/abandeali1',
- medium: 'https://medium.com/@abandeali1',
- },
- {
- name: 'Fabio Berger',
- title: 'Senior Engineer',
- description: `Full-stack blockchain engineer. Previously software engineer \
+ image: '/images/team/amir.jpeg',
+ linkedIn: 'https://www.linkedin.com/in/abandeali1/',
+ github: 'https://github.com/abandeali1',
+ medium: 'https://medium.com/@abandeali1',
+ },
+ {
+ name: 'Fabio Berger',
+ title: 'Senior Engineer',
+ description: `Full-stack blockchain engineer. Previously software engineer \
at Airtable and founder of WealthLift. Computer science at Duke.`,
- image: '/images/team/fabio.jpg',
- linkedIn: 'https://www.linkedin.com/in/fabio-berger-03ab261a/',
- github: 'https://github.com/fabioberger',
- medium: 'https://medium.com/@fabioberger',
- },
+ image: '/images/team/fabio.jpg',
+ linkedIn: 'https://www.linkedin.com/in/fabio-berger-03ab261a/',
+ github: 'https://github.com/fabioberger',
+ medium: 'https://medium.com/@fabioberger',
+ },
];
const teamRow2: ProfileInfo[] = [
- {
- name: 'Alex Xu',
- title: 'Director of Operations',
- description: `Strategy and operations. Previously digital marketing at Google \
+ {
+ name: 'Alex Xu',
+ title: 'Director of Operations',
+ description: `Strategy and operations. Previously digital marketing at Google \
and vendor management at Amazon. Economics at UC San Diego.`,
- image: '/images/team/alex.jpg',
- linkedIn: 'https://www.linkedin.com/in/alex-xu/',
- github: '',
- medium: 'https://medium.com/@aqxu',
- },
- {
- name: 'Leonid Logvinov',
- title: 'Engineer',
- description: `Full-stack blockchain engineer. Previously blockchain engineer \
+ image: '/images/team/alex.jpg',
+ linkedIn: 'https://www.linkedin.com/in/alex-xu/',
+ github: '',
+ medium: 'https://medium.com/@aqxu',
+ },
+ {
+ name: 'Leonid Logvinov',
+ title: 'Engineer',
+ description: `Full-stack blockchain engineer. Previously blockchain engineer \
at Neufund. Computer science at University of Warsaw.`,
- image: '/images/team/leonid.png',
- linkedIn: 'https://www.linkedin.com/in/leonidlogvinov/',
- github: 'https://github.com/LogvinovLeon',
- medium: 'https://medium.com/@Logvinov',
- },
- {
- name: 'Ben Burns',
- title: 'Designer',
- description: `Product, motion, and graphic designer. Previously designer \
+ image: '/images/team/leonid.png',
+ linkedIn: 'https://www.linkedin.com/in/leonidlogvinov/',
+ github: 'https://github.com/LogvinovLeon',
+ medium: 'https://medium.com/@Logvinov',
+ },
+ {
+ name: 'Ben Burns',
+ title: 'Designer',
+ description: `Product, motion, and graphic designer. Previously designer \
at Airtable and Apple. Digital Design at University of Cincinnati.`,
- image: '/images/team/ben.jpg',
- linkedIn: 'https://www.linkedin.com/in/ben-burns-30170478/',
- github: '',
- medium: '',
- },
+ image: '/images/team/ben.jpg',
+ linkedIn: 'https://www.linkedin.com/in/ben-burns-30170478/',
+ github: '',
+ medium: '',
+ },
];
const teamRow3: ProfileInfo[] = [
- {
- name: 'Brandon Millman',
- title: 'Senior Engineer',
- description: `Full-stack engineer. Previously senior software engineer at \
+ {
+ name: 'Brandon Millman',
+ title: 'Senior Engineer',
+ description: `Full-stack engineer. Previously senior software engineer at \
Twitter. Electrical and Computer Engineering at Duke.`,
- image: '/images/team/brandon.png',
- linkedIn: 'https://www.linkedin.com/in/brandon-millman-b093a022/',
- github: 'https://github.com/BMillman19',
- medium: 'https://medium.com/@bchillman',
- },
- {
- name: 'Tom Schmidt',
- title: 'Product Manager',
- description: `Previously engineering at Apple, product management at Facebook and Instagram. Computer Science at Stanford.`,
- image: '/images/team/tom.jpg',
- linkedIn: 'https://www.linkedin.com/in/tomhschmidt/',
- github: 'https://github.com/tomhschmidt',
- medium: '',
- },
- {
- name: 'Jacob Evans',
- title: 'Blockchain Engineer',
- description: `Previously software engineer at Qantas and RSA Security.`,
- image: '/images/team/jacob.jpg',
- linkedIn: 'https://www.linkedin.com/in/dekzter/',
- github: 'https://github.com/dekz',
- medium: '',
- },
+ image: '/images/team/brandon.png',
+ linkedIn: 'https://www.linkedin.com/in/brandon-millman-b093a022/',
+ github: 'https://github.com/BMillman19',
+ medium: 'https://medium.com/@bchillman',
+ },
+ {
+ name: 'Tom Schmidt',
+ title: 'Product Manager',
+ description: `Previously engineering at Apple, product management at Facebook and Instagram. Computer Science at Stanford.`,
+ image: '/images/team/tom.jpg',
+ linkedIn: 'https://www.linkedin.com/in/tomhschmidt/',
+ github: 'https://github.com/tomhschmidt',
+ medium: '',
+ },
+ {
+ name: 'Jacob Evans',
+ title: 'Blockchain Engineer',
+ description: `Previously software engineer at Qantas and RSA Security.`,
+ image: '/images/team/jacob.jpg',
+ linkedIn: 'https://www.linkedin.com/in/dekzter/',
+ github: 'https://github.com/dekz',
+ medium: '',
+ },
];
const advisors: ProfileInfo[] = [
- {
- name: 'Fred Ehrsam',
- description: 'Co-founder of Coinbase. Previously FX trader at Goldman Sachs.',
- image: '/images/advisors/fred.jpg',
- linkedIn: 'https://www.linkedin.com/in/fredehrsam/',
- medium: 'https://medium.com/@FEhrsam',
- twitter: 'https://twitter.com/FEhrsam',
- },
- {
- name: 'Olaf Carlson-Wee',
- image: '/images/advisors/olaf.png',
- description: 'Founder of Polychain Capital. First hire at Coinbase. Angel investor.',
- linkedIn: 'https://www.linkedin.com/in/olafcw/',
- angellist: 'https://angel.co/olafcw',
- },
- {
- name: 'Joey Krug',
- description: `Co-CIO at Pantera Capital. Founder of Augur. Thiel 20 Under 20 Fellow.`,
- image: '/images/advisors/joey.jpg',
- linkedIn: 'https://www.linkedin.com/in/joeykrug/',
- github: 'https://github.com/joeykrug',
- angellist: 'https://angel.co/joeykrug',
- },
- {
- name: 'Linda Xie',
- description: 'Co-founder of Scalar Capital. Previously PM at Coinbase.',
- image: '/images/advisors/linda.jpg',
- linkedIn: 'https://www.linkedin.com/in/lindaxie/',
- medium: 'https://medium.com/@linda.xie',
- twitter: 'https://twitter.com/ljxie',
- },
+ {
+ name: 'Fred Ehrsam',
+ description: 'Co-founder of Coinbase. Previously FX trader at Goldman Sachs.',
+ image: '/images/advisors/fred.jpg',
+ linkedIn: 'https://www.linkedin.com/in/fredehrsam/',
+ medium: 'https://medium.com/@FEhrsam',
+ twitter: 'https://twitter.com/FEhrsam',
+ },
+ {
+ name: 'Olaf Carlson-Wee',
+ image: '/images/advisors/olaf.png',
+ description: 'Founder of Polychain Capital. First hire at Coinbase. Angel investor.',
+ linkedIn: 'https://www.linkedin.com/in/olafcw/',
+ angellist: 'https://angel.co/olafcw',
+ },
+ {
+ name: 'Joey Krug',
+ description: `Co-CIO at Pantera Capital. Founder of Augur. Thiel 20 Under 20 Fellow.`,
+ image: '/images/advisors/joey.jpg',
+ linkedIn: 'https://www.linkedin.com/in/joeykrug/',
+ github: 'https://github.com/joeykrug',
+ angellist: 'https://angel.co/joeykrug',
+ },
+ {
+ name: 'Linda Xie',
+ description: 'Co-founder of Scalar Capital. Previously PM at Coinbase.',
+ image: '/images/advisors/linda.jpg',
+ linkedIn: 'https://www.linkedin.com/in/lindaxie/',
+ medium: 'https://medium.com/@linda.xie',
+ twitter: 'https://twitter.com/ljxie',
+ },
];
export interface AboutProps {
- source: string;
- location: Location;
+ source: string;
+ location: Location;
}
interface AboutState {}
const styles: Styles = {
- header: {
- fontFamily: 'Roboto Mono',
- fontSize: 36,
- color: 'black',
- paddingTop: 110,
- },
- weAreHiring: {
- fontSize: 30,
- color: colors.darkestGrey,
- fontFamily: 'Roboto Mono',
- letterSpacing: 7.5,
- },
+ header: {
+ fontFamily: 'Roboto Mono',
+ fontSize: 36,
+ color: 'black',
+ paddingTop: 110,
+ },
+ weAreHiring: {
+ fontSize: 30,
+ color: colors.darkestGrey,
+ fontFamily: 'Roboto Mono',
+ letterSpacing: 7.5,
+ },
};
export class About extends React.Component<AboutProps, AboutState> {
- public componentDidMount() {
- window.scrollTo(0, 0);
- }
- public render() {
- return (
- <div style={{ backgroundColor: colors.lightestGrey }}>
- <DocumentTitle title="0x About Us" />
- <TopBar
- blockchainIsLoaded={false}
- location={this.props.location}
- style={{ backgroundColor: colors.lightestGrey }}
- />
- <div id="about" className="mx-auto max-width-4 py4" style={{ color: colors.grey800 }}>
- <div className="mx-auto pb4 sm-px3" style={{ maxWidth: 435 }}>
- <div style={styles.header}>About us:</div>
- <div
- className="pt3"
- style={{
- fontSize: 17,
- color: colors.darkestGrey,
- lineHeight: 1.5,
- }}
- >
- Our team is a diverse and globally distributed group with backgrounds in engineering,
- research, business and design. We are passionate about decentralized technology and its
- potential to act as an equalizing force in the world.
- </div>
- </div>
- <div className="pt3 md-px4 lg-px0">
- <div className="clearfix pb3">{this._renderProfiles(teamRow1)}</div>
- <div className="clearfix">{this._renderProfiles(teamRow2)}</div>
- <div className="clearfix">{this._renderProfiles(teamRow3)}</div>
- </div>
- <div className="pt3 pb2">
- <div
- className="pt2 pb3 sm-center md-pl4 lg-pl0 md-ml3"
- style={{
- color: colors.grey,
- fontSize: 24,
- fontFamily: 'Roboto Mono',
- }}
- >
- Advisors:
- </div>
- <div className="clearfix">{this._renderProfiles(advisors)}</div>
- </div>
- <div className="mx-auto py4 sm-px3" style={{ maxWidth: 308 }}>
- <div className="pb2" style={styles.weAreHiring}>
- WE'RE HIRING
- </div>
- <div
- className="pb4 mb4"
- style={{
- fontSize: 16,
- color: colors.darkestGrey,
- lineHeight: 1.5,
- letterSpacing: '0.5px',
- }}
- >
- We are seeking outstanding candidates to{' '}
- <a href={constants.URL_ANGELLIST} target="_blank" style={{ color: 'black' }}>
- join our team
- </a>
- . We value passion, diversity and unique perspectives.
- </div>
- </div>
- </div>
- <Footer />
- </div>
- );
- }
- private _renderProfiles(profiles: ProfileInfo[]) {
- const numIndiv = profiles.length;
- const colSize = utils.getColSize(numIndiv);
- return _.map(profiles, profile => {
- return (
- <div key={`profile-${profile.name}`}>
- <Profile colSize={colSize} profileInfo={profile} />
- </div>
- );
- });
- }
+ public componentDidMount() {
+ window.scrollTo(0, 0);
+ }
+ public render() {
+ return (
+ <div style={{ backgroundColor: colors.lightestGrey }}>
+ <DocumentTitle title="0x About Us" />
+ <TopBar
+ blockchainIsLoaded={false}
+ location={this.props.location}
+ style={{ backgroundColor: colors.lightestGrey }}
+ />
+ <div id="about" className="mx-auto max-width-4 py4" style={{ color: colors.grey800 }}>
+ <div className="mx-auto pb4 sm-px3" style={{ maxWidth: 435 }}>
+ <div style={styles.header}>About us:</div>
+ <div
+ className="pt3"
+ style={{
+ fontSize: 17,
+ color: colors.darkestGrey,
+ lineHeight: 1.5,
+ }}
+ >
+ Our team is a diverse and globally distributed group with backgrounds in engineering,
+ research, business and design. We are passionate about decentralized technology and its
+ potential to act as an equalizing force in the world.
+ </div>
+ </div>
+ <div className="pt3 md-px4 lg-px0">
+ <div className="clearfix pb3">{this._renderProfiles(teamRow1)}</div>
+ <div className="clearfix">{this._renderProfiles(teamRow2)}</div>
+ <div className="clearfix">{this._renderProfiles(teamRow3)}</div>
+ </div>
+ <div className="pt3 pb2">
+ <div
+ className="pt2 pb3 sm-center md-pl4 lg-pl0 md-ml3"
+ style={{
+ color: colors.grey,
+ fontSize: 24,
+ fontFamily: 'Roboto Mono',
+ }}
+ >
+ Advisors:
+ </div>
+ <div className="clearfix">{this._renderProfiles(advisors)}</div>
+ </div>
+ <div className="mx-auto py4 sm-px3" style={{ maxWidth: 308 }}>
+ <div className="pb2" style={styles.weAreHiring}>
+ WE'RE HIRING
+ </div>
+ <div
+ className="pb4 mb4"
+ style={{
+ fontSize: 16,
+ color: colors.darkestGrey,
+ lineHeight: 1.5,
+ letterSpacing: '0.5px',
+ }}
+ >
+ We are seeking outstanding candidates to{' '}
+ <a href={constants.URL_ANGELLIST} target="_blank" style={{ color: 'black' }}>
+ join our team
+ </a>
+ . We value passion, diversity and unique perspectives.
+ </div>
+ </div>
+ </div>
+ <Footer />
+ </div>
+ );
+ }
+ private _renderProfiles(profiles: ProfileInfo[]) {
+ const numIndiv = profiles.length;
+ const colSize = utils.getColSize(numIndiv);
+ return _.map(profiles, profile => {
+ return (
+ <div key={`profile-${profile.name}`}>
+ <Profile colSize={colSize} profileInfo={profile} />
+ </div>
+ );
+ });
+ }
}
diff --git a/packages/website/ts/pages/about/profile.tsx b/packages/website/ts/pages/about/profile.tsx
index f1830851f..18b4e0d5a 100644
--- a/packages/website/ts/pages/about/profile.tsx
+++ b/packages/website/ts/pages/about/profile.tsx
@@ -5,75 +5,75 @@ import { colors } from 'ts/utils/colors';
const IMAGE_DIMENSION = 149;
const styles: Styles = {
- subheader: {
- textTransform: 'uppercase',
- fontSize: 32,
- margin: 0,
- },
- imageContainer: {
- width: IMAGE_DIMENSION,
- height: IMAGE_DIMENSION,
- boxShadow: 'rgba(0, 0, 0, 0.19) 2px 5px 10px',
- },
+ subheader: {
+ textTransform: 'uppercase',
+ fontSize: 32,
+ margin: 0,
+ },
+ imageContainer: {
+ width: IMAGE_DIMENSION,
+ height: IMAGE_DIMENSION,
+ boxShadow: 'rgba(0, 0, 0, 0.19) 2px 5px 10px',
+ },
};
interface ProfileProps {
- colSize: number;
- profileInfo: ProfileInfo;
+ colSize: number;
+ profileInfo: ProfileInfo;
}
export function Profile(props: ProfileProps) {
- return (
- <div className={`lg-col md-col lg-col-${props.colSize} md-col-6`}>
- <div style={{ maxWidth: 300 }} className="mx-auto lg-px3 md-px3 sm-px4 sm-pb3">
- <div className="circle overflow-hidden mx-auto" style={styles.imageContainer}>
- <img width={IMAGE_DIMENSION} src={props.profileInfo.image} />
- </div>
- <div className="center" style={{ fontSize: 18, fontWeight: 'bold', paddingTop: 20 }}>
- {props.profileInfo.name}
- </div>
- {!_.isUndefined(props.profileInfo.title) && (
- <div
- className="pt1 center"
- style={{
- fontSize: 14,
- fontFamily: 'Roboto Mono',
- color: colors.darkGrey,
- }}
- >
- {props.profileInfo.title.toUpperCase()}
- </div>
- )}
- <div style={{ minHeight: 60, lineHeight: 1.4 }} className="pt1 pb2 mx-auto lg-h6 md-h6 sm-h5 sm-center">
- {props.profileInfo.description}
- </div>
- <div className="flex pb3 mx-auto sm-hide xs-hide" style={{ width: 280, opacity: 0.5 }}>
- {renderSocialMediaIcons(props.profileInfo)}
- </div>
- </div>
- </div>
- );
+ return (
+ <div className={`lg-col md-col lg-col-${props.colSize} md-col-6`}>
+ <div style={{ maxWidth: 300 }} className="mx-auto lg-px3 md-px3 sm-px4 sm-pb3">
+ <div className="circle overflow-hidden mx-auto" style={styles.imageContainer}>
+ <img width={IMAGE_DIMENSION} src={props.profileInfo.image} />
+ </div>
+ <div className="center" style={{ fontSize: 18, fontWeight: 'bold', paddingTop: 20 }}>
+ {props.profileInfo.name}
+ </div>
+ {!_.isUndefined(props.profileInfo.title) && (
+ <div
+ className="pt1 center"
+ style={{
+ fontSize: 14,
+ fontFamily: 'Roboto Mono',
+ color: colors.darkGrey,
+ }}
+ >
+ {props.profileInfo.title.toUpperCase()}
+ </div>
+ )}
+ <div style={{ minHeight: 60, lineHeight: 1.4 }} className="pt1 pb2 mx-auto lg-h6 md-h6 sm-h5 sm-center">
+ {props.profileInfo.description}
+ </div>
+ <div className="flex pb3 mx-auto sm-hide xs-hide" style={{ width: 280, opacity: 0.5 }}>
+ {renderSocialMediaIcons(props.profileInfo)}
+ </div>
+ </div>
+ </div>
+ );
}
function renderSocialMediaIcons(profileInfo: ProfileInfo) {
- const icons = [
- renderSocialMediaIcon('zmdi-github-box', profileInfo.github),
- renderSocialMediaIcon('zmdi-linkedin-box', profileInfo.linkedIn),
- renderSocialMediaIcon('zmdi-twitter-box', profileInfo.twitter),
- ];
- return icons;
+ const icons = [
+ renderSocialMediaIcon('zmdi-github-box', profileInfo.github),
+ renderSocialMediaIcon('zmdi-linkedin-box', profileInfo.linkedIn),
+ renderSocialMediaIcon('zmdi-twitter-box', profileInfo.twitter),
+ ];
+ return icons;
}
function renderSocialMediaIcon(iconName: string, url: string) {
- if (_.isEmpty(url)) {
- return null;
- }
+ if (_.isEmpty(url)) {
+ return null;
+ }
- return (
- <div key={url} className="pr1">
- <a href={url} style={{ color: 'inherit' }} target="_blank" className="text-decoration-none">
- <i className={`zmdi ${iconName}`} style={{ ...styles.socalIcon }} />
- </a>
- </div>
- );
+ return (
+ <div key={url} className="pr1">
+ <a href={url} style={{ color: 'inherit' }} target="_blank" className="text-decoration-none">
+ <i className={`zmdi ${iconName}`} style={{ ...styles.socalIcon }} />
+ </a>
+ </div>
+ );
}
diff --git a/packages/website/ts/pages/documentation/comment.tsx b/packages/website/ts/pages/documentation/comment.tsx
index 6be39f586..23cfd96bd 100644
--- a/packages/website/ts/pages/documentation/comment.tsx
+++ b/packages/website/ts/pages/documentation/comment.tsx
@@ -4,20 +4,20 @@ import * as ReactMarkdown from 'react-markdown';
import { MarkdownCodeBlock } from 'ts/pages/shared/markdown_code_block';
interface CommentProps {
- comment: string;
- className?: string;
+ comment: string;
+ className?: string;
}
const defaultProps = {
- className: '',
+ className: '',
};
export const Comment: React.SFC<CommentProps> = (props: CommentProps) => {
- return (
- <div className={`${props.className} comment`}>
- <ReactMarkdown source={props.comment} renderers={{ CodeBlock: MarkdownCodeBlock }} />
- </div>
- );
+ return (
+ <div className={`${props.className} comment`}>
+ <ReactMarkdown source={props.comment} renderers={{ CodeBlock: MarkdownCodeBlock }} />
+ </div>
+ );
};
Comment.defaultProps = defaultProps;
diff --git a/packages/website/ts/pages/documentation/custom_enum.tsx b/packages/website/ts/pages/documentation/custom_enum.tsx
index 0006b8d7e..8d50a2f52 100644
--- a/packages/website/ts/pages/documentation/custom_enum.tsx
+++ b/packages/website/ts/pages/documentation/custom_enum.tsx
@@ -6,27 +6,27 @@ import { utils } from 'ts/utils/utils';
const STRING_ENUM_CODE_PREFIX = ' strEnum(';
interface CustomEnumProps {
- type: CustomType;
+ type: CustomType;
}
// This component renders custom string enums that was a work-around for versions of
// TypeScript <2.4.0 that did not support them natively. We keep it around to support
// older versions of 0x.js <0.9.0
export function CustomEnum(props: CustomEnumProps) {
- const type = props.type;
- if (!_.startsWith(type.defaultValue, STRING_ENUM_CODE_PREFIX)) {
- utils.consoleLog('We do not yet support `Variable` types that are not strEnums');
- return null;
- }
- // Remove the prefix and postfix, leaving only the strEnum values without quotes.
- const enumValues = type.defaultValue.slice(10, -3).replace(/'/g, '');
- return (
- <span>
- {`{`}
- {'\t'}
- {enumValues}
- <br />
- {`}`}
- </span>
- );
+ const type = props.type;
+ if (!_.startsWith(type.defaultValue, STRING_ENUM_CODE_PREFIX)) {
+ utils.consoleLog('We do not yet support `Variable` types that are not strEnums');
+ return null;
+ }
+ // Remove the prefix and postfix, leaving only the strEnum values without quotes.
+ const enumValues = type.defaultValue.slice(10, -3).replace(/'/g, '');
+ return (
+ <span>
+ {`{`}
+ {'\t'}
+ {enumValues}
+ <br />
+ {`}`}
+ </span>
+ );
}
diff --git a/packages/website/ts/pages/documentation/docs_info.ts b/packages/website/ts/pages/documentation/docs_info.ts
index e1080f3a0..4b1ec122a 100644
--- a/packages/website/ts/pages/documentation/docs_info.ts
+++ b/packages/website/ts/pages/documentation/docs_info.ts
@@ -1,111 +1,111 @@
import compareVersions = require('compare-versions');
import * as _ from 'lodash';
import {
- DocAgnosticFormat,
- DocsInfoConfig,
- DocsMenu,
- DoxityDocObj,
- MenuSubsectionsBySection,
- SectionsMap,
- TypeDocNode,
+ DocAgnosticFormat,
+ DocsInfoConfig,
+ DocsMenu,
+ DoxityDocObj,
+ MenuSubsectionsBySection,
+ SectionsMap,
+ TypeDocNode,
} from 'ts/types';
export class DocsInfo {
- public displayName: string;
- public packageUrl: string;
- public subPackageName?: string;
- public websitePath: string;
- public docsJsonRoot: string;
- public menu: DocsMenu;
- public sections: SectionsMap;
- public sectionNameToMarkdown: { [sectionName: string]: string };
- private _docsInfo: DocsInfoConfig;
- constructor(config: DocsInfoConfig) {
- this.displayName = config.displayName;
- this.packageUrl = config.packageUrl;
- this.subPackageName = config.subPackageName;
- this.websitePath = config.websitePath;
- this.docsJsonRoot = config.docsJsonRoot;
- this.sections = config.sections;
- this.sectionNameToMarkdown = config.sectionNameToMarkdown;
- this._docsInfo = config;
- }
- public isPublicType(typeName: string): boolean {
- if (_.isUndefined(this._docsInfo.publicTypes)) {
- return false;
- }
- const isPublic = _.includes(this._docsInfo.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;
- }
+ public displayName: string;
+ public packageUrl: string;
+ public subPackageName?: string;
+ public websitePath: string;
+ public docsJsonRoot: string;
+ public menu: DocsMenu;
+ public sections: SectionsMap;
+ public sectionNameToMarkdown: { [sectionName: string]: string };
+ private _docsInfo: DocsInfoConfig;
+ constructor(config: DocsInfoConfig) {
+ this.displayName = config.displayName;
+ this.packageUrl = config.packageUrl;
+ this.subPackageName = config.subPackageName;
+ this.websitePath = config.websitePath;
+ this.docsJsonRoot = config.docsJsonRoot;
+ this.sections = config.sections;
+ this.sectionNameToMarkdown = config.sectionNameToMarkdown;
+ this._docsInfo = config;
+ }
+ public isPublicType(typeName: string): boolean {
+ if (_.isUndefined(this._docsInfo.publicTypes)) {
+ return false;
+ }
+ const isPublic = _.includes(this._docsInfo.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;
- }
+ const finalMenu = _.cloneDeep(this._docsInfo.menu);
+ if (_.isUndefined(finalMenu.contracts)) {
+ return finalMenu;
+ }
- // 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 existsInSelectedVersion = compareVersions(selectedVersion, versionIntroducedIfExists) >= 0;
- return existsInSelectedVersion;
- } else {
- return true;
- }
- });
- return finalMenu;
- }
- public getMenuSubsectionsBySection(docAgnosticFormat?: DocAgnosticFormat): MenuSubsectionsBySection {
- const menuSubsectionsBySection = {} as MenuSubsectionsBySection;
- if (_.isUndefined(docAgnosticFormat)) {
- return menuSubsectionsBySection;
- }
+ // 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 existsInSelectedVersion = compareVersions(selectedVersion, versionIntroducedIfExists) >= 0;
+ return existsInSelectedVersion;
+ } else {
+ return true;
+ }
+ });
+ return finalMenu;
+ }
+ public getMenuSubsectionsBySection(docAgnosticFormat?: DocAgnosticFormat): MenuSubsectionsBySection {
+ const menuSubsectionsBySection = {} as MenuSubsectionsBySection;
+ if (_.isUndefined(docAgnosticFormat)) {
+ return menuSubsectionsBySection;
+ }
- const docSections = _.keys(this.sections);
- _.each(docSections, sectionName => {
- const docSection = docAgnosticFormat[sectionName];
- if (_.isUndefined(docSection)) {
- return; // no-op
- }
+ const docSections = _.keys(this.sections);
+ _.each(docSections, sectionName => {
+ const docSection = docAgnosticFormat[sectionName];
+ if (_.isUndefined(docSection)) {
+ return; // no-op
+ }
- if (!_.isUndefined(this.sections.types) && sectionName === this.sections.types) {
- const sortedTypesNames = _.sortBy(docSection.types, 'name');
- const typeNames = _.map(sortedTypesNames, t => t.name);
- menuSubsectionsBySection[sectionName] = typeNames;
- } 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];
- }
- });
- return menuSubsectionsBySection;
- }
- public getTypeDefinitionsByName(docAgnosticFormat: DocAgnosticFormat) {
- if (_.isUndefined(this.sections.types)) {
- return {};
- }
+ if (!_.isUndefined(this.sections.types) && sectionName === this.sections.types) {
+ const sortedTypesNames = _.sortBy(docSection.types, 'name');
+ const typeNames = _.map(sortedTypesNames, t => t.name);
+ menuSubsectionsBySection[sectionName] = typeNames;
+ } 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];
+ }
+ });
+ return menuSubsectionsBySection;
+ }
+ public getTypeDefinitionsByName(docAgnosticFormat: DocAgnosticFormat) {
+ if (_.isUndefined(this.sections.types)) {
+ return {};
+ }
- const typeDocSection = docAgnosticFormat[this.sections.types];
- const typeDefinitionByName = _.keyBy(typeDocSection.types, 'name');
- return typeDefinitionByName;
- }
- public isVisibleConstructor(sectionName: string): boolean {
- return _.includes(this._docsInfo.visibleConstructors, sectionName);
- }
- public convertToDocAgnosticFormat(docObj: DoxityDocObj | TypeDocNode): DocAgnosticFormat {
- return this._docsInfo.convertToDocAgnosticFormatFn(docObj, this);
- }
+ const typeDocSection = docAgnosticFormat[this.sections.types];
+ const typeDefinitionByName = _.keyBy(typeDocSection.types, 'name');
+ return typeDefinitionByName;
+ }
+ public isVisibleConstructor(sectionName: string): boolean {
+ return _.includes(this._docsInfo.visibleConstructors, sectionName);
+ }
+ public convertToDocAgnosticFormat(docObj: DoxityDocObj | TypeDocNode): DocAgnosticFormat {
+ return this._docsInfo.convertToDocAgnosticFormatFn(docObj, this);
+ }
}
diff --git a/packages/website/ts/pages/documentation/documentation.tsx b/packages/website/ts/pages/documentation/documentation.tsx
index 0fc41d775..2315847ad 100644
--- a/packages/website/ts/pages/documentation/documentation.tsx
+++ b/packages/website/ts/pages/documentation/documentation.tsx
@@ -19,17 +19,17 @@ import { NestedSidebarMenu } from 'ts/pages/shared/nested_sidebar_menu';
import { SectionHeader } from 'ts/pages/shared/section_header';
import { Dispatcher } from 'ts/redux/dispatcher';
import {
- AddressByContractName,
- DocAgnosticFormat,
- DoxityDocObj,
- EtherscanLinkSuffixes,
- Event,
- Networks,
- Property,
- SolidityMethod,
- Styles,
- TypeDefinitionByName,
- TypescriptMethod,
+ AddressByContractName,
+ DocAgnosticFormat,
+ DoxityDocObj,
+ EtherscanLinkSuffixes,
+ Event,
+ Networks,
+ Property,
+ SolidityMethod,
+ Styles,
+ TypeDefinitionByName,
+ TypescriptMethod,
} from 'ts/types';
import { colors } from 'ts/utils/colors';
import { configs } from 'ts/utils/configs';
@@ -40,340 +40,340 @@ import { utils } from 'ts/utils/utils';
const SCROLL_TOP_ID = 'docsScrollTop';
const networkNameToColor: { [network: string]: string } = {
- [Networks.kovan]: colors.purple,
- [Networks.ropsten]: colors.red,
- [Networks.mainnet]: colors.turquois,
+ [Networks.kovan]: colors.purple,
+ [Networks.ropsten]: colors.red,
+ [Networks.mainnet]: colors.turquois,
};
export interface DocumentationAllProps {
- source: string;
- location: Location;
- dispatcher: Dispatcher;
- docsVersion: string;
- availableDocVersions: string[];
- docsInfo: DocsInfo;
+ source: string;
+ location: Location;
+ dispatcher: Dispatcher;
+ docsVersion: string;
+ availableDocVersions: string[];
+ docsInfo: DocsInfo;
}
interface DocumentationState {
- docAgnosticFormat?: DocAgnosticFormat;
+ docAgnosticFormat?: DocAgnosticFormat;
}
const styles: Styles = {
- mainContainers: {
- position: 'absolute',
- top: 1,
- left: 0,
- bottom: 0,
- right: 0,
- overflowZ: 'hidden',
- overflowY: 'scroll',
- minHeight: 'calc(100vh - 1px)',
- WebkitOverflowScrolling: 'touch',
- },
- menuContainer: {
- borderColor: colors.grey300,
- maxWidth: 330,
- marginLeft: 20,
- },
+ mainContainers: {
+ position: 'absolute',
+ top: 1,
+ left: 0,
+ bottom: 0,
+ right: 0,
+ overflowZ: 'hidden',
+ overflowY: 'scroll',
+ minHeight: 'calc(100vh - 1px)',
+ WebkitOverflowScrolling: 'touch',
+ },
+ menuContainer: {
+ borderColor: colors.grey300,
+ maxWidth: 330,
+ marginLeft: 20,
+ },
};
export class Documentation extends React.Component<DocumentationAllProps, DocumentationState> {
- constructor(props: DocumentationAllProps) {
- super(props);
- this.state = {
- docAgnosticFormat: undefined,
- };
- }
- public componentWillMount() {
- const pathName = this.props.location.pathname;
- const lastSegment = pathName.substr(pathName.lastIndexOf('/') + 1);
- const versions = findVersions(lastSegment);
- const preferredVersionIfExists = versions.length > 0 ? versions[0] : undefined;
- // tslint:disable-next-line:no-floating-promises
- this._fetchJSONDocsFireAndForgetAsync(preferredVersionIfExists);
- }
- public render() {
- const menuSubsectionsBySection = _.isUndefined(this.state.docAgnosticFormat)
- ? {}
- : this.props.docsInfo.getMenuSubsectionsBySection(this.state.docAgnosticFormat);
- return (
- <div>
- <DocumentTitle title={`${this.props.docsInfo.displayName} Documentation`} />
- <TopBar
- blockchainIsLoaded={false}
- location={this.props.location}
- docsVersion={this.props.docsVersion}
- availableDocVersions={this.props.availableDocVersions}
- menu={this.props.docsInfo.getMenu(this.props.docsVersion)}
- menuSubsectionsBySection={menuSubsectionsBySection}
- shouldFullWidth={true}
- docsInfo={this.props.docsInfo}
- />
- {_.isUndefined(this.state.docAgnosticFormat) ? (
- <div className="col col-12" style={styles.mainContainers}>
- <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>
- ) : (
- <div className="mx-auto flex" style={{ color: colors.grey800, height: 43 }}>
- <div className="relative col md-col-3 lg-col-3 lg-pl0 md-pl1 sm-hide xs-hide">
- <div
- className="border-right absolute"
- style={{ ...styles.menuContainer, ...styles.mainContainers }}
- >
- <NestedSidebarMenu
- selectedVersion={this.props.docsVersion}
- versions={this.props.availableDocVersions}
- topLevelMenu={this.props.docsInfo.getMenu(this.props.docsVersion)}
- menuSubsectionsBySection={menuSubsectionsBySection}
- docPath={this.props.docsInfo.websitePath}
- />
- </div>
- </div>
- <div className="relative col lg-col-9 md-col-9 sm-col-12 col-12">
- <div id="documentation" style={styles.mainContainers} className="absolute">
- <div id={SCROLL_TOP_ID} />
- <h1 className="md-pl2 sm-pl3">
- <a href={this.props.docsInfo.packageUrl} target="_blank">
- {this.props.docsInfo.displayName}
- </a>
- </h1>
- {this._renderDocumentation()}
- </div>
- </div>
- </div>
- )}
- </div>
- );
- }
- private _renderDocumentation(): React.ReactNode {
- const subMenus = _.values(this.props.docsInfo.getMenu());
- const orderedSectionNames = _.flatten(subMenus);
+ constructor(props: DocumentationAllProps) {
+ super(props);
+ this.state = {
+ docAgnosticFormat: undefined,
+ };
+ }
+ public componentWillMount() {
+ const pathName = this.props.location.pathname;
+ const lastSegment = pathName.substr(pathName.lastIndexOf('/') + 1);
+ const versions = findVersions(lastSegment);
+ const preferredVersionIfExists = versions.length > 0 ? versions[0] : undefined;
+ // tslint:disable-next-line:no-floating-promises
+ this._fetchJSONDocsFireAndForgetAsync(preferredVersionIfExists);
+ }
+ public render() {
+ const menuSubsectionsBySection = _.isUndefined(this.state.docAgnosticFormat)
+ ? {}
+ : this.props.docsInfo.getMenuSubsectionsBySection(this.state.docAgnosticFormat);
+ return (
+ <div>
+ <DocumentTitle title={`${this.props.docsInfo.displayName} Documentation`} />
+ <TopBar
+ blockchainIsLoaded={false}
+ location={this.props.location}
+ docsVersion={this.props.docsVersion}
+ availableDocVersions={this.props.availableDocVersions}
+ menu={this.props.docsInfo.getMenu(this.props.docsVersion)}
+ menuSubsectionsBySection={menuSubsectionsBySection}
+ shouldFullWidth={true}
+ docsInfo={this.props.docsInfo}
+ />
+ {_.isUndefined(this.state.docAgnosticFormat) ? (
+ <div className="col col-12" style={styles.mainContainers}>
+ <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>
+ ) : (
+ <div className="mx-auto flex" style={{ color: colors.grey800, height: 43 }}>
+ <div className="relative col md-col-3 lg-col-3 lg-pl0 md-pl1 sm-hide xs-hide">
+ <div
+ className="border-right absolute"
+ style={{ ...styles.menuContainer, ...styles.mainContainers }}
+ >
+ <NestedSidebarMenu
+ selectedVersion={this.props.docsVersion}
+ versions={this.props.availableDocVersions}
+ topLevelMenu={this.props.docsInfo.getMenu(this.props.docsVersion)}
+ menuSubsectionsBySection={menuSubsectionsBySection}
+ docPath={this.props.docsInfo.websitePath}
+ />
+ </div>
+ </div>
+ <div className="relative col lg-col-9 md-col-9 sm-col-12 col-12">
+ <div id="documentation" style={styles.mainContainers} className="absolute">
+ <div id={SCROLL_TOP_ID} />
+ <h1 className="md-pl2 sm-pl3">
+ <a href={this.props.docsInfo.packageUrl} target="_blank">
+ {this.props.docsInfo.displayName}
+ </a>
+ </h1>
+ {this._renderDocumentation()}
+ </div>
+ </div>
+ </div>
+ )}
+ </div>
+ );
+ }
+ private _renderDocumentation(): React.ReactNode {
+ const subMenus = _.values(this.props.docsInfo.getMenu());
+ const orderedSectionNames = _.flatten(subMenus);
- const typeDefinitionByName = this.props.docsInfo.getTypeDefinitionsByName(this.state.docAgnosticFormat);
- const renderedSections = _.map(orderedSectionNames, this._renderSection.bind(this, typeDefinitionByName));
+ const typeDefinitionByName = this.props.docsInfo.getTypeDefinitionsByName(this.state.docAgnosticFormat);
+ const renderedSections = _.map(orderedSectionNames, this._renderSection.bind(this, typeDefinitionByName));
- return renderedSections;
- }
- private _renderSection(typeDefinitionByName: TypeDefinitionByName, sectionName: string): React.ReactNode {
- const markdownFileIfExists = this.props.docsInfo.sectionNameToMarkdown[sectionName];
- if (!_.isUndefined(markdownFileIfExists)) {
- return (
- <MarkdownSection
- key={`markdown-section-${sectionName}`}
- sectionName={sectionName}
- markdownContent={markdownFileIfExists}
- />
- );
- }
+ return renderedSections;
+ }
+ private _renderSection(typeDefinitionByName: TypeDefinitionByName, sectionName: string): React.ReactNode {
+ const markdownFileIfExists = this.props.docsInfo.sectionNameToMarkdown[sectionName];
+ if (!_.isUndefined(markdownFileIfExists)) {
+ return (
+ <MarkdownSection
+ key={`markdown-section-${sectionName}`}
+ sectionName={sectionName}
+ markdownContent={markdownFileIfExists}
+ />
+ );
+ }
- const docSection = this.state.docAgnosticFormat[sectionName];
- if (_.isUndefined(docSection)) {
- return null;
- }
+ const docSection = this.state.docAgnosticFormat[sectionName];
+ if (_.isUndefined(docSection)) {
+ return null;
+ }
- const sortedTypes = _.sortBy(docSection.types, 'name');
- const typeDefs = _.map(sortedTypes, customType => {
- return (
- <TypeDefinition
- sectionName={sectionName}
- key={`type-${customType.name}`}
- customType={customType}
- docsInfo={this.props.docsInfo}
- />
- );
- });
+ const sortedTypes = _.sortBy(docSection.types, 'name');
+ const typeDefs = _.map(sortedTypes, customType => {
+ return (
+ <TypeDefinition
+ sectionName={sectionName}
+ key={`type-${customType.name}`}
+ customType={customType}
+ docsInfo={this.props.docsInfo}
+ />
+ );
+ });
- const sortedProperties = _.sortBy(docSection.properties, 'name');
- const propertyDefs = _.map(sortedProperties, this._renderProperty.bind(this, sectionName));
+ const sortedProperties = _.sortBy(docSection.properties, 'name');
+ const propertyDefs = _.map(sortedProperties, this._renderProperty.bind(this, sectionName));
- const sortedMethods = _.sortBy(docSection.methods, 'name');
- const methodDefs = _.map(sortedMethods, method => {
- const isConstructor = false;
- return this._renderMethodBlocks(method, sectionName, isConstructor, typeDefinitionByName);
- });
+ const sortedMethods = _.sortBy(docSection.methods, 'name');
+ const methodDefs = _.map(sortedMethods, method => {
+ const isConstructor = false;
+ return this._renderMethodBlocks(method, sectionName, isConstructor, typeDefinitionByName);
+ });
- const sortedEvents = _.sortBy(docSection.events, 'name');
- const eventDefs = _.map(sortedEvents, (event: Event, i: number) => {
- return (
- <EventDefinition
- key={`event-${event.name}-${i}`}
- event={event}
- sectionName={sectionName}
- docsInfo={this.props.docsInfo}
- />
- );
- });
- return (
- <div key={`section-${sectionName}`} className="py2 pr3 md-pl2 sm-pl3">
- <div className="flex">
- <div style={{ marginRight: 7 }}>
- <SectionHeader sectionName={sectionName} />
- </div>
- {this._renderNetworkBadgesIfExists(sectionName)}
- </div>
- {docSection.comment && <Comment comment={docSection.comment} />}
- {docSection.constructors.length > 0 &&
- this.props.docsInfo.isVisibleConstructor(sectionName) && (
- <div>
- <h2 className="thin">Constructor</h2>
- {this._renderConstructors(docSection.constructors, sectionName, typeDefinitionByName)}
- </div>
- )}
- {docSection.properties.length > 0 && (
- <div>
- <h2 className="thin">Properties</h2>
- <div>{propertyDefs}</div>
- </div>
- )}
- {docSection.methods.length > 0 && (
- <div>
- <h2 className="thin">Methods</h2>
- <div>{methodDefs}</div>
- </div>
- )}
- {!_.isUndefined(docSection.events) &&
- docSection.events.length > 0 && (
- <div>
- <h2 className="thin">Events</h2>
- <div>{eventDefs}</div>
- </div>
- )}
- {!_.isUndefined(typeDefs) &&
- typeDefs.length > 0 && (
- <div>
- <div>{typeDefs}</div>
- </div>
- )}
- </div>
- );
- }
- private _renderNetworkBadgesIfExists(sectionName: string) {
- const networkToAddressByContractName = configs.CONTRACT_ADDRESS[this.props.docsVersion];
- const badges = _.map(
- networkToAddressByContractName,
- (addressByContractName: AddressByContractName, networkName: string) => {
- const contractAddress = addressByContractName[sectionName];
- if (_.isUndefined(contractAddress)) {
- return null;
- }
- const linkIfExists = utils.getEtherScanLinkIfExists(
- contractAddress,
- constants.NETWORK_ID_BY_NAME[networkName],
- 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>
- );
- },
- );
- return badges;
- }
- private _renderConstructors(
- constructors: SolidityMethod[] | TypescriptMethod[],
- sectionName: string,
- typeDefinitionByName: TypeDefinitionByName,
- ): React.ReactNode {
- const constructorDefs = _.map(constructors, constructor => {
- return this._renderMethodBlocks(constructor, sectionName, constructor.isConstructor, typeDefinitionByName);
- });
- return <div>{constructorDefs}</div>;
- }
- private _renderProperty(sectionName: string, property: Property): React.ReactNode {
- return (
- <div key={`property-${property.name}-${property.type.name}`} className="pb3">
- <code className="hljs">
- {property.name}:
- <Type type={property.type} sectionName={sectionName} docsInfo={this.props.docsInfo} />
- </code>
- {property.source && (
- <SourceLink
- version={this.props.docsVersion}
- source={property.source}
- baseUrl={this.props.docsInfo.packageUrl}
- subPackageName={this.props.docsInfo.subPackageName}
- />
- )}
- {property.comment && <Comment comment={property.comment} className="py2" />}
- </div>
- );
- }
- private _renderMethodBlocks(
- method: SolidityMethod | TypescriptMethod,
- sectionName: string,
- isConstructor: boolean,
- typeDefinitionByName: TypeDefinitionByName,
- ): React.ReactNode {
- return (
- <MethodBlock
- key={`method-${method.name}-${sectionName}`}
- sectionName={sectionName}
- method={method}
- typeDefinitionByName={typeDefinitionByName}
- libraryVersion={this.props.docsVersion}
- docsInfo={this.props.docsInfo}
- />
- );
- }
- private _scrollToHash(): void {
- const hashWithPrefix = this.props.location.hash;
- let hash = hashWithPrefix.slice(1);
- if (_.isEmpty(hash)) {
- hash = SCROLL_TOP_ID; // scroll to the top
- }
+ const sortedEvents = _.sortBy(docSection.events, 'name');
+ const eventDefs = _.map(sortedEvents, (event: Event, i: number) => {
+ return (
+ <EventDefinition
+ key={`event-${event.name}-${i}`}
+ event={event}
+ sectionName={sectionName}
+ docsInfo={this.props.docsInfo}
+ />
+ );
+ });
+ return (
+ <div key={`section-${sectionName}`} className="py2 pr3 md-pl2 sm-pl3">
+ <div className="flex">
+ <div style={{ marginRight: 7 }}>
+ <SectionHeader sectionName={sectionName} />
+ </div>
+ {this._renderNetworkBadgesIfExists(sectionName)}
+ </div>
+ {docSection.comment && <Comment comment={docSection.comment} />}
+ {docSection.constructors.length > 0 &&
+ this.props.docsInfo.isVisibleConstructor(sectionName) && (
+ <div>
+ <h2 className="thin">Constructor</h2>
+ {this._renderConstructors(docSection.constructors, sectionName, typeDefinitionByName)}
+ </div>
+ )}
+ {docSection.properties.length > 0 && (
+ <div>
+ <h2 className="thin">Properties</h2>
+ <div>{propertyDefs}</div>
+ </div>
+ )}
+ {docSection.methods.length > 0 && (
+ <div>
+ <h2 className="thin">Methods</h2>
+ <div>{methodDefs}</div>
+ </div>
+ )}
+ {!_.isUndefined(docSection.events) &&
+ docSection.events.length > 0 && (
+ <div>
+ <h2 className="thin">Events</h2>
+ <div>{eventDefs}</div>
+ </div>
+ )}
+ {!_.isUndefined(typeDefs) &&
+ typeDefs.length > 0 && (
+ <div>
+ <div>{typeDefs}</div>
+ </div>
+ )}
+ </div>
+ );
+ }
+ private _renderNetworkBadgesIfExists(sectionName: string) {
+ const networkToAddressByContractName = configs.CONTRACT_ADDRESS[this.props.docsVersion];
+ const badges = _.map(
+ networkToAddressByContractName,
+ (addressByContractName: AddressByContractName, networkName: string) => {
+ const contractAddress = addressByContractName[sectionName];
+ if (_.isUndefined(contractAddress)) {
+ return null;
+ }
+ const linkIfExists = utils.getEtherScanLinkIfExists(
+ contractAddress,
+ constants.NETWORK_ID_BY_NAME[networkName],
+ 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>
+ );
+ },
+ );
+ return badges;
+ }
+ private _renderConstructors(
+ constructors: SolidityMethod[] | TypescriptMethod[],
+ sectionName: string,
+ typeDefinitionByName: TypeDefinitionByName,
+ ): React.ReactNode {
+ const constructorDefs = _.map(constructors, constructor => {
+ return this._renderMethodBlocks(constructor, sectionName, constructor.isConstructor, typeDefinitionByName);
+ });
+ return <div>{constructorDefs}</div>;
+ }
+ private _renderProperty(sectionName: string, property: Property): React.ReactNode {
+ return (
+ <div key={`property-${property.name}-${property.type.name}`} className="pb3">
+ <code className="hljs">
+ {property.name}:
+ <Type type={property.type} sectionName={sectionName} docsInfo={this.props.docsInfo} />
+ </code>
+ {property.source && (
+ <SourceLink
+ version={this.props.docsVersion}
+ source={property.source}
+ baseUrl={this.props.docsInfo.packageUrl}
+ subPackageName={this.props.docsInfo.subPackageName}
+ />
+ )}
+ {property.comment && <Comment comment={property.comment} className="py2" />}
+ </div>
+ );
+ }
+ private _renderMethodBlocks(
+ method: SolidityMethod | TypescriptMethod,
+ sectionName: string,
+ isConstructor: boolean,
+ typeDefinitionByName: TypeDefinitionByName,
+ ): React.ReactNode {
+ return (
+ <MethodBlock
+ key={`method-${method.name}-${sectionName}`}
+ sectionName={sectionName}
+ method={method}
+ typeDefinitionByName={typeDefinitionByName}
+ libraryVersion={this.props.docsVersion}
+ docsInfo={this.props.docsInfo}
+ />
+ );
+ }
+ private _scrollToHash(): void {
+ const hashWithPrefix = this.props.location.hash;
+ let hash = hashWithPrefix.slice(1);
+ if (_.isEmpty(hash)) {
+ hash = SCROLL_TOP_ID; // scroll to the top
+ }
- scroller.scrollTo(hash, {
- duration: 0,
- offset: 0,
- containerId: 'documentation',
- });
- }
- private async _fetchJSONDocsFireAndForgetAsync(preferredVersionIfExists?: string): Promise<void> {
- const versionToFileName = await docUtils.getVersionToFileNameAsync(this.props.docsInfo.docsJsonRoot);
- const versions = _.keys(versionToFileName);
- this.props.dispatcher.updateAvailableDocVersions(versions);
- const sortedVersions = semverSort.desc(versions);
- const latestVersion = sortedVersions[0];
+ scroller.scrollTo(hash, {
+ duration: 0,
+ offset: 0,
+ containerId: 'documentation',
+ });
+ }
+ private async _fetchJSONDocsFireAndForgetAsync(preferredVersionIfExists?: string): Promise<void> {
+ const versionToFileName = await docUtils.getVersionToFileNameAsync(this.props.docsInfo.docsJsonRoot);
+ const versions = _.keys(versionToFileName);
+ this.props.dispatcher.updateAvailableDocVersions(versions);
+ const sortedVersions = semverSort.desc(versions);
+ const latestVersion = sortedVersions[0];
- let versionToFetch = latestVersion;
- if (!_.isUndefined(preferredVersionIfExists)) {
- const preferredVersionFileNameIfExists = versionToFileName[preferredVersionIfExists];
- if (!_.isUndefined(preferredVersionFileNameIfExists)) {
- versionToFetch = preferredVersionIfExists;
- }
- }
- this.props.dispatcher.updateCurrentDocsVersion(versionToFetch);
+ let versionToFetch = latestVersion;
+ if (!_.isUndefined(preferredVersionIfExists)) {
+ const preferredVersionFileNameIfExists = versionToFileName[preferredVersionIfExists];
+ if (!_.isUndefined(preferredVersionFileNameIfExists)) {
+ versionToFetch = preferredVersionIfExists;
+ }
+ }
+ this.props.dispatcher.updateCurrentDocsVersion(versionToFetch);
- const versionFileNameToFetch = versionToFileName[versionToFetch];
- const versionDocObj = await docUtils.getJSONDocFileAsync(
- versionFileNameToFetch,
- this.props.docsInfo.docsJsonRoot,
- );
- const docAgnosticFormat = this.props.docsInfo.convertToDocAgnosticFormat(versionDocObj as DoxityDocObj);
+ const versionFileNameToFetch = versionToFileName[versionToFetch];
+ const versionDocObj = await docUtils.getJSONDocFileAsync(
+ versionFileNameToFetch,
+ this.props.docsInfo.docsJsonRoot,
+ );
+ const docAgnosticFormat = this.props.docsInfo.convertToDocAgnosticFormat(versionDocObj as DoxityDocObj);
- this.setState(
- {
- docAgnosticFormat,
- },
- () => {
- this._scrollToHash();
- },
- );
- }
+ this.setState(
+ {
+ docAgnosticFormat,
+ },
+ () => {
+ this._scrollToHash();
+ },
+ );
+ }
}
diff --git a/packages/website/ts/pages/documentation/enum.tsx b/packages/website/ts/pages/documentation/enum.tsx
index cfcc7f8d7..7dfdee771 100644
--- a/packages/website/ts/pages/documentation/enum.tsx
+++ b/packages/website/ts/pages/documentation/enum.tsx
@@ -3,20 +3,20 @@ import * as React from 'react';
import { EnumValue } from 'ts/types';
interface EnumProps {
- values: EnumValue[];
+ values: EnumValue[];
}
export function Enum(props: EnumProps) {
- const values = _.map(props.values, (value, i) => {
- const defaultValueIfAny = !_.isUndefined(value.defaultValue) ? ` = ${value.defaultValue}` : '';
- return `\n\t${value.name}${defaultValueIfAny},`;
- });
- return (
- <span>
- {`{`}
- {values}
- <br />
- {`}`}
- </span>
- );
+ const values = _.map(props.values, (value, i) => {
+ const defaultValueIfAny = !_.isUndefined(value.defaultValue) ? ` = ${value.defaultValue}` : '';
+ return `\n\t${value.name}${defaultValueIfAny},`;
+ });
+ return (
+ <span>
+ {`{`}
+ {values}
+ <br />
+ {`}`}
+ </span>
+ );
}
diff --git a/packages/website/ts/pages/documentation/event_definition.tsx b/packages/website/ts/pages/documentation/event_definition.tsx
index 9274ae512..0e53e38e7 100644
--- a/packages/website/ts/pages/documentation/event_definition.tsx
+++ b/packages/website/ts/pages/documentation/event_definition.tsx
@@ -7,76 +7,76 @@ import { Event, EventArg, HeaderSizes } from 'ts/types';
import { colors } from 'ts/utils/colors';
interface EventDefinitionProps {
- event: Event;
- sectionName: string;
- docsInfo: DocsInfo;
+ event: Event;
+ sectionName: string;
+ docsInfo: DocsInfo;
}
interface EventDefinitionState {
- shouldShowAnchor: boolean;
+ shouldShowAnchor: boolean;
}
export class EventDefinition extends React.Component<EventDefinitionProps, EventDefinitionState> {
- constructor(props: EventDefinitionProps) {
- super(props);
- this.state = {
- shouldShowAnchor: false,
- };
- }
- public render() {
- const event = this.props.event;
- return (
- <div
- id={`${this.props.sectionName}-${event.name}`}
- className="pb2"
- style={{ overflow: 'hidden', width: '100%' }}
- onMouseOver={this._setAnchorVisibility.bind(this, true)}
- onMouseOut={this._setAnchorVisibility.bind(this, false)}
- >
- <AnchorTitle
- headerSize={HeaderSizes.H3}
- title={`Event ${event.name}`}
- id={event.name}
- shouldShowAnchor={this.state.shouldShowAnchor}
- />
- <div style={{ fontSize: 16 }}>
- <pre>
- <code className="hljs">{this._renderEventCode()}</code>
- </pre>
- </div>
- </div>
- );
- }
- private _renderEventCode() {
- 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} />
- );
- return (
- <span key={`eventArg-${eventArg.name}`}>
- {eventArg.name}
- {eventArg.isIndexed ? indexed : ''}: {type},
- </span>
- );
- });
- const argList = _.reduce(eventArgs, (prev: React.ReactNode, curr: React.ReactNode) => {
- return [prev, '\n\t', curr];
- });
- return (
- <span>
- {`{`}
- <br />
- {'\t'}
- {argList}
- <br />
- {`}`}
- </span>
- );
- }
- private _setAnchorVisibility(shouldShowAnchor: boolean) {
- this.setState({
- shouldShowAnchor,
- });
- }
+ constructor(props: EventDefinitionProps) {
+ super(props);
+ this.state = {
+ shouldShowAnchor: false,
+ };
+ }
+ public render() {
+ const event = this.props.event;
+ return (
+ <div
+ id={`${this.props.sectionName}-${event.name}`}
+ className="pb2"
+ style={{ overflow: 'hidden', width: '100%' }}
+ onMouseOver={this._setAnchorVisibility.bind(this, true)}
+ onMouseOut={this._setAnchorVisibility.bind(this, false)}
+ >
+ <AnchorTitle
+ headerSize={HeaderSizes.H3}
+ title={`Event ${event.name}`}
+ id={event.name}
+ shouldShowAnchor={this.state.shouldShowAnchor}
+ />
+ <div style={{ fontSize: 16 }}>
+ <pre>
+ <code className="hljs">{this._renderEventCode()}</code>
+ </pre>
+ </div>
+ </div>
+ );
+ }
+ private _renderEventCode() {
+ 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} />
+ );
+ return (
+ <span key={`eventArg-${eventArg.name}`}>
+ {eventArg.name}
+ {eventArg.isIndexed ? indexed : ''}: {type},
+ </span>
+ );
+ });
+ const argList = _.reduce(eventArgs, (prev: React.ReactNode, curr: React.ReactNode) => {
+ return [prev, '\n\t', curr];
+ });
+ return (
+ <span>
+ {`{`}
+ <br />
+ {'\t'}
+ {argList}
+ <br />
+ {`}`}
+ </span>
+ );
+ }
+ private _setAnchorVisibility(shouldShowAnchor: boolean) {
+ this.setState({
+ shouldShowAnchor,
+ });
+ }
}
diff --git a/packages/website/ts/pages/documentation/interface.tsx b/packages/website/ts/pages/documentation/interface.tsx
index ee07a2c50..16a772125 100644
--- a/packages/website/ts/pages/documentation/interface.tsx
+++ b/packages/website/ts/pages/documentation/interface.tsx
@@ -6,56 +6,56 @@ import { Type } from 'ts/pages/documentation/type';
import { CustomType, TypeDocTypes } from 'ts/types';
interface InterfaceProps {
- type: CustomType;
- sectionName: string;
- docsInfo: DocsInfo;
+ type: CustomType;
+ sectionName: string;
+ docsInfo: DocsInfo;
}
export function Interface(props: InterfaceProps) {
- const type = props.type;
- const properties = _.map(type.children, property => {
- return (
- <span key={`property-${property.name}-${property.type}-${type.name}`}>
- {property.name}:{' '}
- {property.type.typeDocType !== TypeDocTypes.Reflection ? (
- <Type type={property.type} sectionName={props.sectionName} docsInfo={props.docsInfo} />
- ) : (
- <MethodSignature
- method={property.type.method}
- sectionName={props.sectionName}
- shouldHideMethodName={true}
- shouldUseArrowSyntax={true}
- docsInfo={props.docsInfo}
- />
- )},
- </span>
- );
- });
- const hasIndexSignature = !_.isUndefined(type.indexSignature);
- if (hasIndexSignature) {
- 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} />
- </span>
- );
- properties.push(
- <span key={`indexSignature-${type.name}-${is.keyType.name}`}>
- [{param}]: {is.valueName},
- </span>,
- );
- }
- const propertyList = _.reduce(properties, (prev: React.ReactNode, curr: React.ReactNode) => {
- return [prev, '\n\t', curr];
- });
- return (
- <span>
- {`{`}
- <br />
- {'\t'}
- {propertyList}
- <br />
- {`}`}
- </span>
- );
+ const type = props.type;
+ const properties = _.map(type.children, property => {
+ return (
+ <span key={`property-${property.name}-${property.type}-${type.name}`}>
+ {property.name}:{' '}
+ {property.type.typeDocType !== TypeDocTypes.Reflection ? (
+ <Type type={property.type} sectionName={props.sectionName} docsInfo={props.docsInfo} />
+ ) : (
+ <MethodSignature
+ method={property.type.method}
+ sectionName={props.sectionName}
+ shouldHideMethodName={true}
+ shouldUseArrowSyntax={true}
+ docsInfo={props.docsInfo}
+ />
+ )},
+ </span>
+ );
+ });
+ const hasIndexSignature = !_.isUndefined(type.indexSignature);
+ if (hasIndexSignature) {
+ 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} />
+ </span>
+ );
+ properties.push(
+ <span key={`indexSignature-${type.name}-${is.keyType.name}`}>
+ [{param}]: {is.valueName},
+ </span>,
+ );
+ }
+ const propertyList = _.reduce(properties, (prev: React.ReactNode, curr: React.ReactNode) => {
+ return [prev, '\n\t', curr];
+ });
+ return (
+ <span>
+ {`{`}
+ <br />
+ {'\t'}
+ {propertyList}
+ <br />
+ {`}`}
+ </span>
+ );
}
diff --git a/packages/website/ts/pages/documentation/method_block.tsx b/packages/website/ts/pages/documentation/method_block.tsx
index fb03cf5be..dfde5931b 100644
--- a/packages/website/ts/pages/documentation/method_block.tsx
+++ b/packages/website/ts/pages/documentation/method_block.tsx
@@ -10,133 +10,133 @@ import { colors } from 'ts/utils/colors';
import { typeDocUtils } from 'ts/utils/typedoc_utils';
interface MethodBlockProps {
- method: SolidityMethod | TypescriptMethod;
- sectionName: string;
- libraryVersion: string;
- typeDefinitionByName: TypeDefinitionByName;
- docsInfo: DocsInfo;
+ method: SolidityMethod | TypescriptMethod;
+ sectionName: string;
+ libraryVersion: string;
+ typeDefinitionByName: TypeDefinitionByName;
+ docsInfo: DocsInfo;
}
interface MethodBlockState {
- shouldShowAnchor: boolean;
+ shouldShowAnchor: boolean;
}
const styles: Styles = {
- chip: {
- fontSize: 13,
- backgroundColor: colors.lightBlueA700,
- color: colors.white,
- height: 11,
- borderRadius: 14,
- marginTop: 19,
- lineHeight: 0.8,
- },
+ chip: {
+ fontSize: 13,
+ backgroundColor: colors.lightBlueA700,
+ color: colors.white,
+ height: 11,
+ borderRadius: 14,
+ marginTop: 19,
+ lineHeight: 0.8,
+ },
};
export class MethodBlock extends React.Component<MethodBlockProps, MethodBlockState> {
- constructor(props: MethodBlockProps) {
- super(props);
- this.state = {
- shouldShowAnchor: false,
- };
- }
- public render() {
- const method = this.props.method;
- if (typeDocUtils.isPrivateOrProtectedProperty(method.name)) {
- return null;
- }
+ constructor(props: MethodBlockProps) {
+ super(props);
+ this.state = {
+ shouldShowAnchor: false,
+ };
+ }
+ public render() {
+ const method = this.props.method;
+ if (typeDocUtils.isPrivateOrProtectedProperty(method.name)) {
+ return null;
+ }
- return (
- <div
- id={`${this.props.sectionName}-${method.name}`}
- style={{ overflow: 'hidden', width: '100%' }}
- className="pb4"
- onMouseOver={this._setAnchorVisibility.bind(this, true)}
- onMouseOut={this._setAnchorVisibility.bind(this, false)}
- >
- {!method.isConstructor && (
- <div className="flex">
- {(method as TypescriptMethod).isStatic && this._renderChip('Static')}
- {(method as SolidityMethod).isConstant && this._renderChip('Constant')}
- {(method as SolidityMethod).isPayable && this._renderChip('Payable')}
- <AnchorTitle
- headerSize={HeaderSizes.H3}
- title={method.name}
- id={`${this.props.sectionName}-${method.name}`}
- shouldShowAnchor={this.state.shouldShowAnchor}
- />
- </div>
- )}
- <code className="hljs">
- <MethodSignature
- method={method}
- sectionName={this.props.sectionName}
- typeDefinitionByName={this.props.typeDefinitionByName}
- docsInfo={this.props.docsInfo}
- />
- </code>
- {(method as TypescriptMethod).source && (
- <SourceLink
- version={this.props.libraryVersion}
- source={(method as TypescriptMethod).source}
- baseUrl={this.props.docsInfo.packageUrl}
- subPackageName={this.props.docsInfo.subPackageName}
- />
- )}
- {method.comment && <Comment comment={method.comment} className="py2" />}
- {method.parameters &&
- !_.isEmpty(method.parameters) && (
- <div>
- <h4 className="pb1 thin" style={{ borderBottom: '1px solid #e1e8ed' }}>
- ARGUMENTS
- </h4>
- {this._renderParameterDescriptions(method.parameters)}
- </div>
- )}
- {method.returnComment && (
- <div className="pt1 comment">
- <h4 className="pb1 thin" style={{ borderBottom: '1px solid #e1e8ed' }}>
- RETURNS
- </h4>
- <Comment comment={method.returnComment} />
- </div>
- )}
- </div>
- );
- }
- private _renderChip(text: string) {
- return (
- <div className="p1 mr1" style={styles.chip}>
- {text}
- </div>
- );
- }
- private _renderParameterDescriptions(parameters: Parameter[]) {
- const descriptions = _.map(parameters, parameter => {
- const isOptional = parameter.isOptional;
- return (
- <div
- key={`param-description-${parameter.name}`}
- className="flex pb1 mb2"
- style={{ borderBottom: '1px solid #f0f4f7' }}
- >
- <div className="pl2 col lg-col-4 md-col-4 sm-col-12 col-12">
- <div className="bold">{parameter.name}</div>
- <div className="pt1" style={{ color: colors.grey, fontSize: 14 }}>
- {isOptional && 'optional'}
- </div>
- </div>
- <div className="col lg-col-8 md-col-8 sm-col-12 col-12">
- {parameter.comment && <Comment comment={parameter.comment} />}
- </div>
- </div>
- );
- });
- return descriptions;
- }
- private _setAnchorVisibility(shouldShowAnchor: boolean) {
- this.setState({
- shouldShowAnchor,
- });
- }
+ return (
+ <div
+ id={`${this.props.sectionName}-${method.name}`}
+ style={{ overflow: 'hidden', width: '100%' }}
+ className="pb4"
+ onMouseOver={this._setAnchorVisibility.bind(this, true)}
+ onMouseOut={this._setAnchorVisibility.bind(this, false)}
+ >
+ {!method.isConstructor && (
+ <div className="flex">
+ {(method as TypescriptMethod).isStatic && this._renderChip('Static')}
+ {(method as SolidityMethod).isConstant && this._renderChip('Constant')}
+ {(method as SolidityMethod).isPayable && this._renderChip('Payable')}
+ <AnchorTitle
+ headerSize={HeaderSizes.H3}
+ title={method.name}
+ id={`${this.props.sectionName}-${method.name}`}
+ shouldShowAnchor={this.state.shouldShowAnchor}
+ />
+ </div>
+ )}
+ <code className="hljs">
+ <MethodSignature
+ method={method}
+ sectionName={this.props.sectionName}
+ typeDefinitionByName={this.props.typeDefinitionByName}
+ docsInfo={this.props.docsInfo}
+ />
+ </code>
+ {(method as TypescriptMethod).source && (
+ <SourceLink
+ version={this.props.libraryVersion}
+ source={(method as TypescriptMethod).source}
+ baseUrl={this.props.docsInfo.packageUrl}
+ subPackageName={this.props.docsInfo.subPackageName}
+ />
+ )}
+ {method.comment && <Comment comment={method.comment} className="py2" />}
+ {method.parameters &&
+ !_.isEmpty(method.parameters) && (
+ <div>
+ <h4 className="pb1 thin" style={{ borderBottom: '1px solid #e1e8ed' }}>
+ ARGUMENTS
+ </h4>
+ {this._renderParameterDescriptions(method.parameters)}
+ </div>
+ )}
+ {method.returnComment && (
+ <div className="pt1 comment">
+ <h4 className="pb1 thin" style={{ borderBottom: '1px solid #e1e8ed' }}>
+ RETURNS
+ </h4>
+ <Comment comment={method.returnComment} />
+ </div>
+ )}
+ </div>
+ );
+ }
+ private _renderChip(text: string) {
+ return (
+ <div className="p1 mr1" style={styles.chip}>
+ {text}
+ </div>
+ );
+ }
+ private _renderParameterDescriptions(parameters: Parameter[]) {
+ const descriptions = _.map(parameters, parameter => {
+ const isOptional = parameter.isOptional;
+ return (
+ <div
+ key={`param-description-${parameter.name}`}
+ className="flex pb1 mb2"
+ style={{ borderBottom: '1px solid #f0f4f7' }}
+ >
+ <div className="pl2 col lg-col-4 md-col-4 sm-col-12 col-12">
+ <div className="bold">{parameter.name}</div>
+ <div className="pt1" style={{ color: colors.grey, fontSize: 14 }}>
+ {isOptional && 'optional'}
+ </div>
+ </div>
+ <div className="col lg-col-8 md-col-8 sm-col-12 col-12">
+ {parameter.comment && <Comment comment={parameter.comment} />}
+ </div>
+ </div>
+ );
+ });
+ return descriptions;
+ }
+ private _setAnchorVisibility(shouldShowAnchor: boolean) {
+ this.setState({
+ shouldShowAnchor,
+ });
+ }
}
diff --git a/packages/website/ts/pages/documentation/method_signature.tsx b/packages/website/ts/pages/documentation/method_signature.tsx
index 7c6bf96d2..041dcd093 100644
--- a/packages/website/ts/pages/documentation/method_signature.tsx
+++ b/packages/website/ts/pages/documentation/method_signature.tsx
@@ -6,94 +6,94 @@ import { Parameter, SolidityMethod, TypeDefinitionByName, TypescriptMethod } fro
import { constants } from 'ts/utils/constants';
interface MethodSignatureProps {
- method: TypescriptMethod | SolidityMethod;
- sectionName: string;
- shouldHideMethodName?: boolean;
- shouldUseArrowSyntax?: boolean;
- typeDefinitionByName?: TypeDefinitionByName;
- docsInfo: DocsInfo;
+ method: TypescriptMethod | SolidityMethod;
+ sectionName: string;
+ shouldHideMethodName?: boolean;
+ shouldUseArrowSyntax?: boolean;
+ typeDefinitionByName?: TypeDefinitionByName;
+ docsInfo: DocsInfo;
}
const defaultProps = {
- shouldHideMethodName: false,
- shouldUseArrowSyntax: false,
+ shouldHideMethodName: false,
+ shouldUseArrowSyntax: false,
};
export const MethodSignature: React.SFC<MethodSignatureProps> = (props: MethodSignatureProps) => {
- const sectionName = constants.TYPES_SECTION_NAME;
- const parameters = renderParameters(props.method, props.docsInfo, sectionName, props.typeDefinitionByName);
- const paramString = _.reduce(parameters, (prev: React.ReactNode, curr: React.ReactNode) => {
- return [prev, ', ', curr];
- });
- const methodName = props.shouldHideMethodName ? '' : props.method.name;
- const typeParameterIfExists = _.isUndefined((props.method as TypescriptMethod).typeParameter)
- ? undefined
- : renderTypeParameter(props.method, props.docsInfo, sectionName, props.typeDefinitionByName);
- return (
- <span>
- {props.method.callPath}
- {methodName}
- {typeParameterIfExists}({paramString})
- {props.shouldUseArrowSyntax ? ' => ' : ': '}{' '}
- {props.method.returnType && (
- <Type
- type={props.method.returnType}
- sectionName={sectionName}
- typeDefinitionByName={props.typeDefinitionByName}
- docsInfo={props.docsInfo}
- />
- )}
- </span>
- );
+ const sectionName = constants.TYPES_SECTION_NAME;
+ const parameters = renderParameters(props.method, props.docsInfo, sectionName, props.typeDefinitionByName);
+ const paramString = _.reduce(parameters, (prev: React.ReactNode, curr: React.ReactNode) => {
+ return [prev, ', ', curr];
+ });
+ const methodName = props.shouldHideMethodName ? '' : props.method.name;
+ const typeParameterIfExists = _.isUndefined((props.method as TypescriptMethod).typeParameter)
+ ? undefined
+ : renderTypeParameter(props.method, props.docsInfo, sectionName, props.typeDefinitionByName);
+ return (
+ <span>
+ {props.method.callPath}
+ {methodName}
+ {typeParameterIfExists}({paramString})
+ {props.shouldUseArrowSyntax ? ' => ' : ': '}{' '}
+ {props.method.returnType && (
+ <Type
+ type={props.method.returnType}
+ sectionName={sectionName}
+ typeDefinitionByName={props.typeDefinitionByName}
+ docsInfo={props.docsInfo}
+ />
+ )}
+ </span>
+ );
};
MethodSignature.defaultProps = defaultProps;
function renderParameters(
- method: TypescriptMethod | SolidityMethod,
- docsInfo: DocsInfo,
- sectionName: string,
- typeDefinitionByName?: TypeDefinitionByName,
+ method: TypescriptMethod | SolidityMethod,
+ docsInfo: DocsInfo,
+ sectionName: string,
+ typeDefinitionByName?: TypeDefinitionByName,
) {
- const parameters = method.parameters;
- const params = _.map(parameters, (p: Parameter) => {
- const isOptional = p.isOptional;
- const type = (
- <Type
- type={p.type}
- sectionName={sectionName}
- typeDefinitionByName={typeDefinitionByName}
- docsInfo={docsInfo}
- />
- );
- return (
- <span key={`param-${p.type}-${p.name}`}>
- {p.name}
- {isOptional && '?'}: {type}
- </span>
- );
- });
- return params;
+ const parameters = method.parameters;
+ const params = _.map(parameters, (p: Parameter) => {
+ const isOptional = p.isOptional;
+ const type = (
+ <Type
+ type={p.type}
+ sectionName={sectionName}
+ typeDefinitionByName={typeDefinitionByName}
+ docsInfo={docsInfo}
+ />
+ );
+ return (
+ <span key={`param-${p.type}-${p.name}`}>
+ {p.name}
+ {isOptional && '?'}: {type}
+ </span>
+ );
+ });
+ return params;
}
function renderTypeParameter(
- method: TypescriptMethod,
- docsInfo: DocsInfo,
- sectionName: string,
- typeDefinitionByName?: TypeDefinitionByName,
+ method: TypescriptMethod,
+ docsInfo: DocsInfo,
+ sectionName: string,
+ typeDefinitionByName?: TypeDefinitionByName,
) {
- const typeParameter = method.typeParameter;
- const typeParam = (
- <span>
- {`<${typeParameter.name} extends `}
- <Type
- type={typeParameter.type}
- sectionName={sectionName}
- typeDefinitionByName={typeDefinitionByName}
- docsInfo={docsInfo}
- />
- {`>`}
- </span>
- );
- return typeParam;
+ const typeParameter = method.typeParameter;
+ const typeParam = (
+ <span>
+ {`<${typeParameter.name} extends `}
+ <Type
+ type={typeParameter.type}
+ sectionName={sectionName}
+ typeDefinitionByName={typeDefinitionByName}
+ docsInfo={docsInfo}
+ />
+ {`>`}
+ </span>
+ );
+ return typeParam;
}
diff --git a/packages/website/ts/pages/documentation/source_link.tsx b/packages/website/ts/pages/documentation/source_link.tsx
index 32126b7da..6588ee39e 100644
--- a/packages/website/ts/pages/documentation/source_link.tsx
+++ b/packages/website/ts/pages/documentation/source_link.tsx
@@ -4,28 +4,28 @@ import { Source } from 'ts/types';
import { colors } from 'ts/utils/colors';
interface SourceLinkProps {
- source: Source;
- baseUrl: string;
- version: string;
- subPackageName: string;
+ source: Source;
+ baseUrl: string;
+ version: string;
+ subPackageName: string;
}
const packagesWithNamespace = ['connect'];
export function SourceLink(props: SourceLinkProps) {
- const src = props.source;
- const url = props.baseUrl;
- const pkg = props.subPackageName;
- let tagPrefix = pkg;
- if (_.includes(packagesWithNamespace, pkg)) {
- tagPrefix = `@0xproject/${pkg}`;
- }
- const sourceCodeUrl = `${url}/blob/${tagPrefix}%40${props.version}/packages/${pkg}/${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>
- </div>
- );
+ const src = props.source;
+ const url = props.baseUrl;
+ const pkg = props.subPackageName;
+ let tagPrefix = pkg;
+ if (_.includes(packagesWithNamespace, pkg)) {
+ tagPrefix = `@0xproject/${pkg}`;
+ }
+ const sourceCodeUrl = `${url}/blob/${tagPrefix}%40${props.version}/packages/${pkg}/${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>
+ </div>
+ );
}
diff --git a/packages/website/ts/pages/documentation/type.tsx b/packages/website/ts/pages/documentation/type.tsx
index 9a2696e22..e989e7129 100644
--- a/packages/website/ts/pages/documentation/type.tsx
+++ b/packages/website/ts/pages/documentation/type.tsx
@@ -11,202 +11,202 @@ import { utils } from 'ts/utils/utils';
// Some types reference other libraries. For these types, we want to link the user to the relevant documentation.
const typeToUrl: { [typeName: string]: string } = {
- Web3: constants.URL_WEB3_DOCS,
- Provider: constants.URL_WEB3_PROVIDER_DOCS,
- BigNumber: constants.URL_BIGNUMBERJS_GITHUB,
- DecodedLogEntryEvent: constants.URL_WEB3_DECODED_LOG_ENTRY_EVENT,
- LogEntryEvent: constants.URL_WEB3_LOG_ENTRY_EVENT,
+ Web3: constants.URL_WEB3_DOCS,
+ Provider: constants.URL_WEB3_PROVIDER_DOCS,
+ BigNumber: constants.URL_BIGNUMBERJS_GITHUB,
+ DecodedLogEntryEvent: constants.URL_WEB3_DECODED_LOG_ENTRY_EVENT,
+ LogEntryEvent: constants.URL_WEB3_LOG_ENTRY_EVENT,
};
const typePrefix: { [typeName: string]: string } = {
- Provider: 'Web3',
- DecodedLogEntryEvent: 'Web3',
- LogEntryEvent: 'Web3',
+ Provider: 'Web3',
+ DecodedLogEntryEvent: 'Web3',
+ LogEntryEvent: 'Web3',
};
const typeToSection: { [typeName: string]: string } = {
- ExchangeWrapper: 'exchange',
- TokenWrapper: 'token',
- TokenRegistryWrapper: 'tokenRegistry',
- EtherTokenWrapper: 'etherToken',
- ProxyWrapper: 'proxy',
- TokenTransferProxyWrapper: 'proxy',
- OrderStateWatcher: 'orderWatcher',
+ ExchangeWrapper: 'exchange',
+ TokenWrapper: 'token',
+ TokenRegistryWrapper: 'tokenRegistry',
+ EtherTokenWrapper: 'etherToken',
+ ProxyWrapper: 'proxy',
+ TokenTransferProxyWrapper: 'proxy',
+ OrderStateWatcher: 'orderWatcher',
};
interface TypeProps {
- type: TypeDef;
- docsInfo: DocsInfo;
- sectionName: string;
- typeDefinitionByName?: TypeDefinitionByName;
+ type: TypeDef;
+ docsInfo: DocsInfo;
+ sectionName: string;
+ typeDefinitionByName?: TypeDefinitionByName;
}
// 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 {
- const type = props.type;
- const isReference = type.typeDocType === TypeDocTypes.Reference;
- const isArray = type.typeDocType === TypeDocTypes.Array;
- let typeNameColor = 'inherit';
- let typeName: string | React.ReactNode;
- let typeArgs: React.ReactNode[] = [];
- switch (type.typeDocType) {
- case TypeDocTypes.Intrinsic:
- case TypeDocTypes.Unknown:
- typeName = type.name;
- typeNameColor = colors.orange;
- break;
+ const type = props.type;
+ const isReference = type.typeDocType === TypeDocTypes.Reference;
+ const isArray = type.typeDocType === TypeDocTypes.Array;
+ let typeNameColor = 'inherit';
+ let typeName: string | React.ReactNode;
+ let typeArgs: React.ReactNode[] = [];
+ switch (type.typeDocType) {
+ case TypeDocTypes.Intrinsic:
+ case TypeDocTypes.Unknown:
+ typeName = type.name;
+ typeNameColor = colors.orange;
+ break;
- case TypeDocTypes.Reference:
- typeName = type.name;
- typeArgs = _.map(type.typeArguments, (arg: TypeDef) => {
- if (arg.typeDocType === TypeDocTypes.Array) {
- const key = `type-${arg.elementType.name}-${arg.elementType.typeDocType}`;
- return (
- <span>
- <Type
- key={key}
- type={arg.elementType}
- sectionName={props.sectionName}
- typeDefinitionByName={props.typeDefinitionByName}
- docsInfo={props.docsInfo}
- />[]
- </span>
- );
- } else {
- const subType = (
- <Type
- key={`type-${arg.name}-${arg.value}-${arg.typeDocType}`}
- type={arg}
- sectionName={props.sectionName}
- typeDefinitionByName={props.typeDefinitionByName}
- docsInfo={props.docsInfo}
- />
- );
- return subType;
- }
- });
- break;
+ case TypeDocTypes.Reference:
+ typeName = type.name;
+ typeArgs = _.map(type.typeArguments, (arg: TypeDef) => {
+ if (arg.typeDocType === TypeDocTypes.Array) {
+ const key = `type-${arg.elementType.name}-${arg.elementType.typeDocType}`;
+ return (
+ <span>
+ <Type
+ key={key}
+ type={arg.elementType}
+ sectionName={props.sectionName}
+ typeDefinitionByName={props.typeDefinitionByName}
+ docsInfo={props.docsInfo}
+ />[]
+ </span>
+ );
+ } else {
+ const subType = (
+ <Type
+ key={`type-${arg.name}-${arg.value}-${arg.typeDocType}`}
+ type={arg}
+ sectionName={props.sectionName}
+ typeDefinitionByName={props.typeDefinitionByName}
+ docsInfo={props.docsInfo}
+ />
+ );
+ return subType;
+ }
+ });
+ break;
- case TypeDocTypes.StringLiteral:
- typeName = `'${type.value}'`;
- typeNameColor = colors.green;
- break;
+ case TypeDocTypes.StringLiteral:
+ typeName = `'${type.value}'`;
+ typeNameColor = colors.green;
+ break;
- case TypeDocTypes.Array:
- typeName = type.elementType.name;
- break;
+ case TypeDocTypes.Array:
+ typeName = type.elementType.name;
+ break;
- case TypeDocTypes.Union:
- const unionTypes = _.map(type.types, t => {
- return (
- <Type
- key={`type-${t.name}-${t.value}-${t.typeDocType}`}
- type={t}
- sectionName={props.sectionName}
- typeDefinitionByName={props.typeDefinitionByName}
- docsInfo={props.docsInfo}
- />
- );
- });
- typeName = _.reduce(unionTypes, (prev: React.ReactNode, curr: React.ReactNode) => {
- return [prev, '|', curr];
- });
- break;
+ case TypeDocTypes.Union:
+ const unionTypes = _.map(type.types, t => {
+ return (
+ <Type
+ key={`type-${t.name}-${t.value}-${t.typeDocType}`}
+ type={t}
+ sectionName={props.sectionName}
+ typeDefinitionByName={props.typeDefinitionByName}
+ docsInfo={props.docsInfo}
+ />
+ );
+ });
+ typeName = _.reduce(unionTypes, (prev: React.ReactNode, curr: React.ReactNode) => {
+ return [prev, '|', curr];
+ });
+ break;
- case TypeDocTypes.TypeParameter:
- typeName = type.name;
- break;
+ case TypeDocTypes.TypeParameter:
+ typeName = type.name;
+ break;
- default:
- throw utils.spawnSwitchErr('type.typeDocType', type.typeDocType);
- }
- // HACK: Normalize BigNumber to simply BigNumber. For some reason the type
- // name is unpredictably one or the other.
- if (typeName === 'BigNumber') {
- typeName = 'BigNumber';
- }
- const commaSeparatedTypeArgs = _.reduce(typeArgs, (prev: React.ReactNode, curr: React.ReactNode) => {
- return [prev, ', ', curr];
- });
+ default:
+ throw utils.spawnSwitchErr('type.typeDocType', type.typeDocType);
+ }
+ // HACK: Normalize BigNumber to simply BigNumber. For some reason the type
+ // name is unpredictably one or the other.
+ if (typeName === 'BigNumber') {
+ typeName = 'BigNumber';
+ }
+ const commaSeparatedTypeArgs = _.reduce(typeArgs, (prev: React.ReactNode, curr: React.ReactNode) => {
+ return [prev, ', ', curr];
+ });
- const typeNameUrlIfExists = typeToUrl[typeName as string];
- const typePrefixIfExists = typePrefix[typeName as string];
- const sectionNameIfExists = typeToSection[typeName as string];
- if (!_.isUndefined(typeNameUrlIfExists)) {
- typeName = (
- <a
- href={typeNameUrlIfExists}
- target="_blank"
- className="text-decoration-none"
- style={{ color: colors.lightBlueA700 }}
- >
- {!_.isUndefined(typePrefixIfExists) ? `${typePrefixIfExists}.` : ''}
- {typeName}
- </a>
- );
- } else if (
- (isReference || isArray) &&
- (props.docsInfo.isPublicType(typeName as string) || !_.isUndefined(sectionNameIfExists))
- ) {
- const id = Math.random().toString();
- const typeDefinitionAnchorId = _.isUndefined(sectionNameIfExists)
- ? `${props.sectionName}-${typeName}`
- : sectionNameIfExists;
- let typeDefinition;
- if (props.typeDefinitionByName) {
- typeDefinition = props.typeDefinitionByName[typeName as string];
- }
- typeName = (
- <ScrollLink
- to={typeDefinitionAnchorId}
- offset={0}
- duration={constants.DOCS_SCROLL_DURATION_MS}
- containerId={constants.DOCS_CONTAINER_ID}
- >
- {_.isUndefined(typeDefinition) || utils.isUserOnMobile() ? (
- <span
- onClick={utils.setUrlHash.bind(null, typeDefinitionAnchorId)}
- style={{ color: colors.lightBlueA700, cursor: 'pointer' }}
- >
- {typeName}
- </span>
- ) : (
- <span
- data-tip={true}
- data-for={id}
- onClick={utils.setUrlHash.bind(null, typeDefinitionAnchorId)}
- style={{
- color: colors.lightBlueA700,
- cursor: 'pointer',
- display: 'inline-block',
- }}
- >
- {typeName}
- <ReactTooltip type="light" effect="solid" id={id} className="typeTooltip">
- <TypeDefinition
- sectionName={props.sectionName}
- customType={typeDefinition}
- shouldAddId={false}
- docsInfo={props.docsInfo}
- />
- </ReactTooltip>
- </span>
- )}
- </ScrollLink>
- );
- }
- return (
- <span>
- <span style={{ color: typeNameColor }}>{typeName}</span>
- {isArray && '[]'}
- {!_.isEmpty(typeArgs) && (
- <span>
- {'<'}
- {commaSeparatedTypeArgs}
- {'>'}
- </span>
- )}
- </span>
- );
+ const typeNameUrlIfExists = typeToUrl[typeName as string];
+ const typePrefixIfExists = typePrefix[typeName as string];
+ const sectionNameIfExists = typeToSection[typeName as string];
+ if (!_.isUndefined(typeNameUrlIfExists)) {
+ typeName = (
+ <a
+ href={typeNameUrlIfExists}
+ target="_blank"
+ className="text-decoration-none"
+ style={{ color: colors.lightBlueA700 }}
+ >
+ {!_.isUndefined(typePrefixIfExists) ? `${typePrefixIfExists}.` : ''}
+ {typeName}
+ </a>
+ );
+ } else if (
+ (isReference || isArray) &&
+ (props.docsInfo.isPublicType(typeName as string) || !_.isUndefined(sectionNameIfExists))
+ ) {
+ const id = Math.random().toString();
+ const typeDefinitionAnchorId = _.isUndefined(sectionNameIfExists)
+ ? `${props.sectionName}-${typeName}`
+ : sectionNameIfExists;
+ let typeDefinition;
+ if (props.typeDefinitionByName) {
+ typeDefinition = props.typeDefinitionByName[typeName as string];
+ }
+ typeName = (
+ <ScrollLink
+ to={typeDefinitionAnchorId}
+ offset={0}
+ duration={constants.DOCS_SCROLL_DURATION_MS}
+ containerId={constants.DOCS_CONTAINER_ID}
+ >
+ {_.isUndefined(typeDefinition) || utils.isUserOnMobile() ? (
+ <span
+ onClick={utils.setUrlHash.bind(null, typeDefinitionAnchorId)}
+ style={{ color: colors.lightBlueA700, cursor: 'pointer' }}
+ >
+ {typeName}
+ </span>
+ ) : (
+ <span
+ data-tip={true}
+ data-for={id}
+ onClick={utils.setUrlHash.bind(null, typeDefinitionAnchorId)}
+ style={{
+ color: colors.lightBlueA700,
+ cursor: 'pointer',
+ display: 'inline-block',
+ }}
+ >
+ {typeName}
+ <ReactTooltip type="light" effect="solid" id={id} className="typeTooltip">
+ <TypeDefinition
+ sectionName={props.sectionName}
+ customType={typeDefinition}
+ shouldAddId={false}
+ docsInfo={props.docsInfo}
+ />
+ </ReactTooltip>
+ </span>
+ )}
+ </ScrollLink>
+ );
+ }
+ return (
+ <span>
+ <span style={{ color: typeNameColor }}>{typeName}</span>
+ {isArray && '[]'}
+ {!_.isEmpty(typeArgs) && (
+ <span>
+ {'<'}
+ {commaSeparatedTypeArgs}
+ {'>'}
+ </span>
+ )}
+ </span>
+ );
}
diff --git a/packages/website/ts/pages/documentation/type_definition.tsx b/packages/website/ts/pages/documentation/type_definition.tsx
index 356926157..d46eec76c 100644
--- a/packages/website/ts/pages/documentation/type_definition.tsx
+++ b/packages/website/ts/pages/documentation/type_definition.tsx
@@ -13,113 +13,113 @@ import { colors } from 'ts/utils/colors';
import { utils } from 'ts/utils/utils';
interface TypeDefinitionProps {
- sectionName: string;
- customType: CustomType;
- shouldAddId?: boolean;
- docsInfo: DocsInfo;
+ sectionName: string;
+ customType: CustomType;
+ shouldAddId?: boolean;
+ docsInfo: DocsInfo;
}
interface TypeDefinitionState {
- shouldShowAnchor: boolean;
+ shouldShowAnchor: boolean;
}
export class TypeDefinition extends React.Component<TypeDefinitionProps, TypeDefinitionState> {
- public static defaultProps: Partial<TypeDefinitionProps> = {
- shouldAddId: true,
- };
- constructor(props: TypeDefinitionProps) {
- super(props);
- this.state = {
- shouldShowAnchor: false,
- };
- }
- public render() {
- const customType = this.props.customType;
- if (!this.props.docsInfo.isPublicType(customType.name)) {
- return null; // no-op
- }
+ public static defaultProps: Partial<TypeDefinitionProps> = {
+ shouldAddId: true,
+ };
+ constructor(props: TypeDefinitionProps) {
+ super(props);
+ this.state = {
+ shouldShowAnchor: false,
+ };
+ }
+ public render() {
+ 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';
- codeSnippet = (
- <Interface type={customType} sectionName={this.props.sectionName} docsInfo={this.props.docsInfo} />
- );
- break;
+ let typePrefix: string;
+ let codeSnippet: React.ReactNode;
+ switch (customType.kindString) {
+ case KindString.Interface:
+ typePrefix = 'Interface';
+ codeSnippet = (
+ <Interface type={customType} sectionName={this.props.sectionName} docsInfo={this.props.docsInfo} />
+ );
+ break;
- case KindString.Variable:
- typePrefix = 'Enum';
- codeSnippet = <CustomEnum type={customType} />;
- break;
+ case KindString.Variable:
+ typePrefix = 'Enum';
+ codeSnippet = <CustomEnum type={customType} />;
+ break;
- case KindString.Enumeration:
- typePrefix = 'Enum';
- const enumValues = _.map(customType.children, (c: CustomTypeChild) => {
- return {
- name: c.name,
- defaultValue: c.defaultValue,
- };
- });
- codeSnippet = <Enum values={enumValues} />;
- break;
+ case KindString.Enumeration:
+ typePrefix = 'Enum';
+ const enumValues = _.map(customType.children, (c: CustomTypeChild) => {
+ return {
+ name: c.name,
+ defaultValue: c.defaultValue,
+ };
+ });
+ codeSnippet = <Enum values={enumValues} />;
+ break;
- case KindString.TypeAlias:
- typePrefix = 'Type Alias';
- codeSnippet = (
- <span>
- <span style={{ color: colors.lightPurple }}>type</span> {customType.name} ={' '}
- {customType.type.typeDocType !== TypeDocTypes.Reflection ? (
- <Type
- type={customType.type}
- sectionName={this.props.sectionName}
- docsInfo={this.props.docsInfo}
- />
- ) : (
- <MethodSignature
- method={customType.type.method}
- sectionName={this.props.sectionName}
- shouldHideMethodName={true}
- shouldUseArrowSyntax={true}
- docsInfo={this.props.docsInfo}
- />
- )}
- </span>
- );
- break;
+ case KindString.TypeAlias:
+ typePrefix = 'Type Alias';
+ codeSnippet = (
+ <span>
+ <span style={{ color: colors.lightPurple }}>type</span> {customType.name} ={' '}
+ {customType.type.typeDocType !== TypeDocTypes.Reflection ? (
+ <Type
+ type={customType.type}
+ sectionName={this.props.sectionName}
+ docsInfo={this.props.docsInfo}
+ />
+ ) : (
+ <MethodSignature
+ method={customType.type.method}
+ sectionName={this.props.sectionName}
+ shouldHideMethodName={true}
+ shouldUseArrowSyntax={true}
+ docsInfo={this.props.docsInfo}
+ />
+ )}
+ </span>
+ );
+ break;
- default:
- throw utils.spawnSwitchErr('type.kindString', customType.kindString);
- }
+ default:
+ throw utils.spawnSwitchErr('type.kindString', customType.kindString);
+ }
- const typeDefinitionAnchorId = `${this.props.sectionName}-${customType.name}`;
- return (
- <div
- id={this.props.shouldAddId ? typeDefinitionAnchorId : ''}
- className="pb2"
- style={{ overflow: 'hidden', width: '100%' }}
- onMouseOver={this._setAnchorVisibility.bind(this, true)}
- onMouseOut={this._setAnchorVisibility.bind(this, false)}
- >
- <AnchorTitle
- headerSize={HeaderSizes.H3}
- title={`${typePrefix} ${customType.name}`}
- id={this.props.shouldAddId ? typeDefinitionAnchorId : ''}
- shouldShowAnchor={this.state.shouldShowAnchor}
- />
- <div style={{ fontSize: 16 }}>
- <pre>
- <code className="hljs">{codeSnippet}</code>
- </pre>
- </div>
- {customType.comment && <Comment comment={customType.comment} className="py2" />}
- </div>
- );
- }
- private _setAnchorVisibility(shouldShowAnchor: boolean) {
- this.setState({
- shouldShowAnchor,
- });
- }
+ const typeDefinitionAnchorId = `${this.props.sectionName}-${customType.name}`;
+ return (
+ <div
+ id={this.props.shouldAddId ? typeDefinitionAnchorId : ''}
+ className="pb2"
+ style={{ overflow: 'hidden', width: '100%' }}
+ onMouseOver={this._setAnchorVisibility.bind(this, true)}
+ onMouseOut={this._setAnchorVisibility.bind(this, false)}
+ >
+ <AnchorTitle
+ headerSize={HeaderSizes.H3}
+ title={`${typePrefix} ${customType.name}`}
+ id={this.props.shouldAddId ? typeDefinitionAnchorId : ''}
+ shouldShowAnchor={this.state.shouldShowAnchor}
+ />
+ <div style={{ fontSize: 16 }}>
+ <pre>
+ <code className="hljs">{codeSnippet}</code>
+ </pre>
+ </div>
+ {customType.comment && <Comment comment={customType.comment} className="py2" />}
+ </div>
+ );
+ }
+ private _setAnchorVisibility(shouldShowAnchor: boolean) {
+ this.setState({
+ shouldShowAnchor,
+ });
+ }
}
diff --git a/packages/website/ts/pages/faq/faq.tsx b/packages/website/ts/pages/faq/faq.tsx
index f437f5a8d..b4b5214a2 100644
--- a/packages/website/ts/pages/faq/faq.tsx
+++ b/packages/website/ts/pages/faq/faq.tsx
@@ -10,438 +10,438 @@ import { configs } from 'ts/utils/configs';
import { constants } from 'ts/utils/constants';
export interface FAQProps {
- source: string;
- location: Location;
+ source: string;
+ location: Location;
}
interface FAQState {}
const styles: Styles = {
- thin: {
- fontWeight: 100,
- },
+ thin: {
+ fontWeight: 100,
+ },
};
const sections: FAQSection[] = [
- {
- name: '0x Protocol',
- questions: [
- {
- prompt: 'What is 0x?',
- answer: (
- <div>
- At its core, 0x is an open and non-rent seeking protocol that facilitates trustless, low
- friction exchange of Ethereum-based assets. Developers can use 0x as a platform to build
- exchange applications on top of (<a
- href={`${configs.BASE_URL}${WebsitePaths.ZeroExJs}#introduction`}
- target="blank"
- >
- 0x.js
- </a>{' '}
- is a Javascript library for interacting with the 0x protocol). For end users, 0x will be the
- infrastructure of a wide variety of user-facing applications i.e.{' '}
- <a href={`${configs.BASE_URL}${WebsitePaths.Portal}`} target="blank">
- 0x Portal
- </a>, a decentralized application that facilitates trustless trading of Ethereum-based tokens
- between known counterparties.
- </div>
- ),
- },
- {
- prompt: 'What problem does 0x solve?',
- answer: (
- <div>
- In the two years since the Ethereum blockchain’s genesis block, numerous decentralized
- applications (dApps) have created Ethereum smart contracts for peer-to-peer exchange. Rapid
- iteration and a lack of best practices have left the blockchain scattered with proprietary and
- application-specific implementations. As a result, end users are exposed to numerous smart
- contracts of varying quality and security, with unique configuration processes and learning
- curves, all of which implement the same functionality. This approach imposes unnecessary costs
- on the network by fragmenting end users according to the particular dApp each user happens to be
- using, eliminating valuable network effects around liquidity. 0x is the solution to this problem
- by acting as modular, unopinionated building blocks that may be assembled and reconfigured.
- </div>
- ),
- },
- {
- prompt: 'How is 0x different from a centralized exchange like Poloniex or ShapeShift?',
- answer: (
- <div>
- <ul>
- <li>0x is a protocol for exchange, not a user-facing exchange application.</li>
- <li>
- 0x is decentralized and trustless; there is no central party which can be hacked, run
- away with customer funds or be subjected to government regulations. Hacks of Mt. Gox,
- Shapeshift and Bitfinex have demonstrated that these types of systemic risks are
- palpable.
- </li>
- <li>
- Rather than a proprietary system that exists to extract rent for its owners, 0x is
- public infrastructure that is funded by a globally distributed community of
- stakeholders. While the protocol is free to use, it enables for-profit user-facing
- exchange applications to be built on top of the protocol.
- </li>
- </ul>
- </div>
- ),
- },
- {
- prompt: 'If 0x protocol is free to use, where do transaction fees come in?',
- answer: (
- <div>
- 0x protocol uses off-chain order books to massively reduce friction costs for market makers and
- ensure that the blockchain is only used for trade settlement. Hosting and maintaining an
- off-chain order book is a service; to incent “Relayers” to provide this service they must be
- able to charge transaction fees on trading activity. Relayers are free to set their transaction
- fees to any value they desire. We expect Relayers to be highly competitive and transaction fees
- to approach an efficient economic equilibrium over time.
- </div>
- ),
- },
- {
- prompt: 'What are the differences between 0x protocol and state channels?',
- answer: (
- <div>
- <div>
- Participants in a state channel pass cryptographically signed messages back and forth,
- accumulating intermediate state changes without publishing them to the canonical chain until
- the channel is closed. State channels are ideal for “bar tab” applications where numerous
- intermediate state changes may be accumulated off-chain before being settled by a final
- on-chain transaction (i.e. day trading, poker, turn-based games).
- </div>
- <ul>
- <li>
- While state channels drastically reduce the number of on-chain transactions for specific
- use cases, numerous on-chain transactions and a security deposit are required to open
- and safely close a state channel making them less efficient than 0x for executing
- one-time trades.
- </li>
- <li>
- State channels are isolated from the Ethereum blockchain meaning that they cannot
- interact with smart contracts. 0x is designed to be integrated directly into smart
- contracts so trades can be executed programmatically in a single line of Solidity code.
- </li>
- </ul>
- </div>
- ),
- },
- {
- prompt: 'What types of digital assets are supported by 0x?',
- answer: (
- <div>
- 0x supports all Ethereum-based assets that adhere to the ERC20 token standard. There are many
- ERC20 tokens, worth a combined $2.2B, and more tokens are created each month. We believe that,
- by 2020, thousands of assets will be tokenized and moved onto the Ethereum blockchain including
- traditional securities such as equities, bonds and derivatives, fiat currencies and scarce
- digital goods such as video game items. In the future, cross-blockchain solutions such as{' '}
- <a href="https://cosmos.network/" target="_blank">
- Cosmos
- </a>{' '}
- and{' '}
- <a href="http://polkadot.io/" target="_blank">
- Polkadot
- </a>{' '}
- will allow cryptocurrencies to freely move between blockchains and, naturally, currencies such
- as Bitcoin will end up being represented as ERC20 tokens on the Ethereum blockchain.
- </div>
- ),
- },
- {
- prompt: '0x is open source: what prevents someone from forking the protocol?',
- answer: (
- <div>
- Ethereum and Bitcoin are both open source protocols. Each protocol has been forked, but the
- resulting clone networks have seen little adoption (as measured by transaction count or market
- cap). This is because users have little to no incentive to switch over to a clone network if the
- original has initial network effects and a talented developer team behind it. An exception is in
- the case that a protocol includes a controversial feature such as a method of rent extraction or
- a monetary policy that favors one group of users over another (Zcash developer subsidy - for
- better or worse - resulted in Zclassic). Perceived inequality can provide a strong enough
- incentive that users will fork the original protocol’s codebase and spin up a new network that
- eliminates the controversial feature. In the case of 0x, there is no rent extraction and no
- users are given special permissions. 0x protocol is upgradable. Cutting-edge technical
- capabilities can be integrated into 0x via decentralized governance (see section below),
- eliminating incentives to fork off of the original protocol and sacrifice the network effects
- surrounding liquidity that result from the shared protocol and settlement layer.
- </div>
- ),
- },
- ],
- },
- {
- name: '0x Token (ZRX)',
- questions: [
- {
- prompt: 'Explain how the 0x protocol token (zrx) works.',
- answer: (
- <div>
- <div>
- 0x protocol token (ZRX) is utilized in two ways: 1) to solve the{' '}
- <a href="https://en.wikipedia.org/wiki/Coordination_game" target="_blank">
- coordination problem
- </a>{' '}
- and drive network effects around liquidity, creating a feedback loop where early adopters of
- the protocol benefit from wider adoption and 2) to be used for decentralized governance over
- 0x protocol's update mechanism. In more detail:
- </div>
- <ul>
- <li>
- ZRX tokens are used by Makers and Takers (market participants that generate and consume
- orders, respectively) to pay transaction fees to Relayers (entities that host and
- maintain public order books).
- </li>
- <li>
- ZRX tokens are used for decentralized governance over 0x protocol’s update mechanism
- which allows its underlying smart contracts to be replaced and improved over time. An
- update mechanism is needed because 0x is built upon Ethereum’s rapidly evolving
- technology stack, decentralized governance is needed because 0x protocol’s smart
- contracts will have access to user funds and numerous dApps will need to plug into 0x
- smart contracts. Decentralized governance ensures that this update process is secure and
- minimizes disruption to the network.
- </li>
- </ul>
- </div>
- ),
- },
- {
- prompt: 'Why must transaction fees be denominated in 0x token (ZRX) rather than ETH?',
- answer: (
- <div>
- 0x protocol’s decentralized update mechanism is analogous to proof-of-stake. To maximize the
- alignment of stakeholder and end user incentives, the staked asset must provide utility within
- the protocol.
- </div>
- ),
- },
- {
- prompt: 'How will decentralized governance work?',
- answer: (
- <div>
- Decentralized governance is an ongoing focus of research; it will involve token voting with ZRX.
- Ultimately the solution will maximize security while also maximizing the protocol’s ability to
- absorb new innovations. Until the governance structure is formalized and encoded within 0x DAO,
- a multi-sig will be used as a placeholder.
- </div>
- ),
- },
- ],
- },
- {
- name: 'ZRX Token Launch and Fund Use',
- questions: [
- {
- prompt: 'What is the total supply of ZRX tokens?',
- answer: <div>1,000,000,000 ZRX. Fixed supply.</div>,
- },
- {
- prompt: 'When is the Token Launch? will there be a pre-sale?',
- answer: <div>The token launch will be on August 15th, 2017. There will not be a pre-sale.</div>,
- },
- {
- prompt: 'What will the token launch proceeds be used for?',
- answer: (
- <div>
- 100% of the proceeds raised in the token launch will be used to fund the development of free and
- open source software, tools and infrastructure that support the protocol and surrounding
- ecosystem. Check out our{' '}
- <a
- href="https://docs.google.com/document/d/1_RVa-_bkU92fWRsC8eNy4vYjcTt-WC8GtqyyjbTd-oY"
- target="_blank"
- >
- development roadmap
- </a>.
- </div>
- ),
- },
- {
- prompt: 'What will be the initial distribution of ZRX tokens?',
- answer: (
- <div>
- <div className="center" style={{ width: '100%' }}>
- <img style={{ width: 350 }} src="/images/zrx_pie_chart.png" />
- </div>
- <div className="py1">
- <div className="bold pb1">Token Launch (50%)</div>
- <div>
- ZRX is inherently a governance token that plays a critical role in the process of
- upgrading 0x protocol. We are fully committed to formulating a functional and
- theoretically sound governance model and we plan to dedicate significant resources to
- R&D.
- </div>
- </div>
- <div className="py1">
- <div className="bold pb1">Retained by 0x (15%)</div>
- <div>
- The 0x core development team will be able to sustain itself for approximately five years
- using funds raised through the token launch. If 0x protocol proves to be as foundational
- a technology as we believe it to be, the retained ZRX tokens will allow the 0x core
- development team to sustain operations beyond the first 5 years.
- </div>
- </div>
- <div className="py1">
- <div className="bold pb1">Developer Fund (15%)</div>
- <div>
- The Developer Fund will be used to make targeted capital injections into high potential
- projects and teams that are attempting to grow the 0x ecosystem, strategic partnerships,
- hackathon prizes and community development activities.
- </div>
- </div>
- <div className="py1">
- <div className="bold pb1">Founding Team (10%)</div>
- <div>
- The founding team’s allocation of ZRX will vest over a traditional 4 year vesting
- schedule with a one year cliff. We believe this should be standard practice for any team
- that is committed to making their project a long term success.
- </div>
- </div>
- <div className="py1">
- <div className="bold pb1">Early Backers & Advisors (10%)</div>
- <div>
- Our backers and advisors have provided capital, resources and guidance that have allowed
- us to fill out our team, setup a robust legal entity and build a fully functional
- product before launching a token. As a result, we have a proven track record and can
- offer a token that holds genuine utility.
- </div>
- </div>
- </div>
- ),
- },
- {
- prompt: 'Can I mine ZRX tokens?',
- answer: (
- <div>
- No, the total supply of ZRX tokens is fixed and there is no continuous issuance model. Users
- that facilitate trading over 0x protocol by operating a Relayer earn transaction fees
- denominated in ZRX; as more trading activity is generated, more transaction fees are earned.
- </div>
- ),
- },
- {
- prompt: 'Will there be a lockup period for ZRX tokens sold in the token launch?',
- answer: <div>No, ZRX tokens sold in the token launch will immediately be liquid.</div>,
- },
- {
- prompt: 'Will there be a lockup period for tokens allocated to the founding team?',
- answer: (
- <div>
- Yes. ZRX tokens allocated to founders, advisors and staff members will be released over a 4 year
- vesting schedule with a 25% cliff upon completion of the initial token launch and 25% released
- each subsequent year in monthly installments. Staff members hired after the token launch will
- have a 4 year vesting schedule with a one year cliff.
- </div>
- ),
- },
- {
- prompt: 'Which cryptocurrencies will be accepted in the token launch?',
- answer: <div>ETH.</div>,
- },
- {
- prompt: 'When will 0x be live?',
- answer: (
- <div>
- An alpha version of 0x has been live on our private test network since January 2017. Version 1.0
- of 0x protocol will be deployed to the canonical Ethereum blockchain after a round of security
- audits and prior to the public token launch. 0x will be using the 0x protocol during our token
- launch.
- </div>
- ),
- },
- {
- prompt: 'Where can I find a development roadmap?',
- answer: (
- <div>
- Check it out{' '}
- <a
- href="https://drive.google.com/open?id=14IP1N8mt3YdsAoqYTyruMnZswpklUs3THyS1VXx71fo"
- target="_blank"
- >
- here
- </a>.
- </div>
- ),
- },
- ],
- },
- {
- name: 'Team',
- questions: [
- {
- prompt: 'Where is 0x based?',
- answer: <div>0x was founded in SF and is driven by a diverse group of contributors.</div>,
- },
- {
- prompt: 'How can I get involved?',
- answer: (
- <div>
- Join our{' '}
- <a href={constants.URL_ZEROEX_CHAT} target="_blank">
- Rocket.chat
- </a>! As an open source project, 0x will rely on a worldwide community of passionate developers
- to contribute proposals, ideas and code.
- </div>
- ),
- },
- {
- prompt: 'Why the name 0x?',
- answer: (
- <div>
- 0x is the prefix for hexadecimal numeric constants including Ethereum addresses. In a more
- abstract context, as the first open protocol for exchange 0x represents the beginning of the end
- for the exchange industry’s rent seeking oligopoly: zero exchange.
- </div>
- ),
- },
- {
- prompt: 'How do you pronounce 0x?',
- answer: <div>We pronounce 0x as “zero-ex,” but you are free to pronounce it however you please.</div>,
- },
- ],
- },
+ {
+ name: '0x Protocol',
+ questions: [
+ {
+ prompt: 'What is 0x?',
+ answer: (
+ <div>
+ At its core, 0x is an open and non-rent seeking protocol that facilitates trustless, low
+ friction exchange of Ethereum-based assets. Developers can use 0x as a platform to build
+ exchange applications on top of (<a
+ href={`${configs.BASE_URL}${WebsitePaths.ZeroExJs}#introduction`}
+ target="blank"
+ >
+ 0x.js
+ </a>{' '}
+ is a Javascript library for interacting with the 0x protocol). For end users, 0x will be the
+ infrastructure of a wide variety of user-facing applications i.e.{' '}
+ <a href={`${configs.BASE_URL}${WebsitePaths.Portal}`} target="blank">
+ 0x Portal
+ </a>, a decentralized application that facilitates trustless trading of Ethereum-based tokens
+ between known counterparties.
+ </div>
+ ),
+ },
+ {
+ prompt: 'What problem does 0x solve?',
+ answer: (
+ <div>
+ In the two years since the Ethereum blockchain’s genesis block, numerous decentralized
+ applications (dApps) have created Ethereum smart contracts for peer-to-peer exchange. Rapid
+ iteration and a lack of best practices have left the blockchain scattered with proprietary and
+ application-specific implementations. As a result, end users are exposed to numerous smart
+ contracts of varying quality and security, with unique configuration processes and learning
+ curves, all of which implement the same functionality. This approach imposes unnecessary costs
+ on the network by fragmenting end users according to the particular dApp each user happens to be
+ using, eliminating valuable network effects around liquidity. 0x is the solution to this problem
+ by acting as modular, unopinionated building blocks that may be assembled and reconfigured.
+ </div>
+ ),
+ },
+ {
+ prompt: 'How is 0x different from a centralized exchange like Poloniex or ShapeShift?',
+ answer: (
+ <div>
+ <ul>
+ <li>0x is a protocol for exchange, not a user-facing exchange application.</li>
+ <li>
+ 0x is decentralized and trustless; there is no central party which can be hacked, run
+ away with customer funds or be subjected to government regulations. Hacks of Mt. Gox,
+ Shapeshift and Bitfinex have demonstrated that these types of systemic risks are
+ palpable.
+ </li>
+ <li>
+ Rather than a proprietary system that exists to extract rent for its owners, 0x is
+ public infrastructure that is funded by a globally distributed community of
+ stakeholders. While the protocol is free to use, it enables for-profit user-facing
+ exchange applications to be built on top of the protocol.
+ </li>
+ </ul>
+ </div>
+ ),
+ },
+ {
+ prompt: 'If 0x protocol is free to use, where do transaction fees come in?',
+ answer: (
+ <div>
+ 0x protocol uses off-chain order books to massively reduce friction costs for market makers and
+ ensure that the blockchain is only used for trade settlement. Hosting and maintaining an
+ off-chain order book is a service; to incent “Relayers” to provide this service they must be
+ able to charge transaction fees on trading activity. Relayers are free to set their transaction
+ fees to any value they desire. We expect Relayers to be highly competitive and transaction fees
+ to approach an efficient economic equilibrium over time.
+ </div>
+ ),
+ },
+ {
+ prompt: 'What are the differences between 0x protocol and state channels?',
+ answer: (
+ <div>
+ <div>
+ Participants in a state channel pass cryptographically signed messages back and forth,
+ accumulating intermediate state changes without publishing them to the canonical chain until
+ the channel is closed. State channels are ideal for “bar tab” applications where numerous
+ intermediate state changes may be accumulated off-chain before being settled by a final
+ on-chain transaction (i.e. day trading, poker, turn-based games).
+ </div>
+ <ul>
+ <li>
+ While state channels drastically reduce the number of on-chain transactions for specific
+ use cases, numerous on-chain transactions and a security deposit are required to open
+ and safely close a state channel making them less efficient than 0x for executing
+ one-time trades.
+ </li>
+ <li>
+ State channels are isolated from the Ethereum blockchain meaning that they cannot
+ interact with smart contracts. 0x is designed to be integrated directly into smart
+ contracts so trades can be executed programmatically in a single line of Solidity code.
+ </li>
+ </ul>
+ </div>
+ ),
+ },
+ {
+ prompt: 'What types of digital assets are supported by 0x?',
+ answer: (
+ <div>
+ 0x supports all Ethereum-based assets that adhere to the ERC20 token standard. There are many
+ ERC20 tokens, worth a combined $2.2B, and more tokens are created each month. We believe that,
+ by 2020, thousands of assets will be tokenized and moved onto the Ethereum blockchain including
+ traditional securities such as equities, bonds and derivatives, fiat currencies and scarce
+ digital goods such as video game items. In the future, cross-blockchain solutions such as{' '}
+ <a href="https://cosmos.network/" target="_blank">
+ Cosmos
+ </a>{' '}
+ and{' '}
+ <a href="http://polkadot.io/" target="_blank">
+ Polkadot
+ </a>{' '}
+ will allow cryptocurrencies to freely move between blockchains and, naturally, currencies such
+ as Bitcoin will end up being represented as ERC20 tokens on the Ethereum blockchain.
+ </div>
+ ),
+ },
+ {
+ prompt: '0x is open source: what prevents someone from forking the protocol?',
+ answer: (
+ <div>
+ Ethereum and Bitcoin are both open source protocols. Each protocol has been forked, but the
+ resulting clone networks have seen little adoption (as measured by transaction count or market
+ cap). This is because users have little to no incentive to switch over to a clone network if the
+ original has initial network effects and a talented developer team behind it. An exception is in
+ the case that a protocol includes a controversial feature such as a method of rent extraction or
+ a monetary policy that favors one group of users over another (Zcash developer subsidy - for
+ better or worse - resulted in Zclassic). Perceived inequality can provide a strong enough
+ incentive that users will fork the original protocol’s codebase and spin up a new network that
+ eliminates the controversial feature. In the case of 0x, there is no rent extraction and no
+ users are given special permissions. 0x protocol is upgradable. Cutting-edge technical
+ capabilities can be integrated into 0x via decentralized governance (see section below),
+ eliminating incentives to fork off of the original protocol and sacrifice the network effects
+ surrounding liquidity that result from the shared protocol and settlement layer.
+ </div>
+ ),
+ },
+ ],
+ },
+ {
+ name: '0x Token (ZRX)',
+ questions: [
+ {
+ prompt: 'Explain how the 0x protocol token (zrx) works.',
+ answer: (
+ <div>
+ <div>
+ 0x protocol token (ZRX) is utilized in two ways: 1) to solve the{' '}
+ <a href="https://en.wikipedia.org/wiki/Coordination_game" target="_blank">
+ coordination problem
+ </a>{' '}
+ and drive network effects around liquidity, creating a feedback loop where early adopters of
+ the protocol benefit from wider adoption and 2) to be used for decentralized governance over
+ 0x protocol's update mechanism. In more detail:
+ </div>
+ <ul>
+ <li>
+ ZRX tokens are used by Makers and Takers (market participants that generate and consume
+ orders, respectively) to pay transaction fees to Relayers (entities that host and
+ maintain public order books).
+ </li>
+ <li>
+ ZRX tokens are used for decentralized governance over 0x protocol’s update mechanism
+ which allows its underlying smart contracts to be replaced and improved over time. An
+ update mechanism is needed because 0x is built upon Ethereum’s rapidly evolving
+ technology stack, decentralized governance is needed because 0x protocol’s smart
+ contracts will have access to user funds and numerous dApps will need to plug into 0x
+ smart contracts. Decentralized governance ensures that this update process is secure and
+ minimizes disruption to the network.
+ </li>
+ </ul>
+ </div>
+ ),
+ },
+ {
+ prompt: 'Why must transaction fees be denominated in 0x token (ZRX) rather than ETH?',
+ answer: (
+ <div>
+ 0x protocol’s decentralized update mechanism is analogous to proof-of-stake. To maximize the
+ alignment of stakeholder and end user incentives, the staked asset must provide utility within
+ the protocol.
+ </div>
+ ),
+ },
+ {
+ prompt: 'How will decentralized governance work?',
+ answer: (
+ <div>
+ Decentralized governance is an ongoing focus of research; it will involve token voting with ZRX.
+ Ultimately the solution will maximize security while also maximizing the protocol’s ability to
+ absorb new innovations. Until the governance structure is formalized and encoded within 0x DAO,
+ a multi-sig will be used as a placeholder.
+ </div>
+ ),
+ },
+ ],
+ },
+ {
+ name: 'ZRX Token Launch and Fund Use',
+ questions: [
+ {
+ prompt: 'What is the total supply of ZRX tokens?',
+ answer: <div>1,000,000,000 ZRX. Fixed supply.</div>,
+ },
+ {
+ prompt: 'When is the Token Launch? will there be a pre-sale?',
+ answer: <div>The token launch will be on August 15th, 2017. There will not be a pre-sale.</div>,
+ },
+ {
+ prompt: 'What will the token launch proceeds be used for?',
+ answer: (
+ <div>
+ 100% of the proceeds raised in the token launch will be used to fund the development of free and
+ open source software, tools and infrastructure that support the protocol and surrounding
+ ecosystem. Check out our{' '}
+ <a
+ href="https://docs.google.com/document/d/1_RVa-_bkU92fWRsC8eNy4vYjcTt-WC8GtqyyjbTd-oY"
+ target="_blank"
+ >
+ development roadmap
+ </a>.
+ </div>
+ ),
+ },
+ {
+ prompt: 'What will be the initial distribution of ZRX tokens?',
+ answer: (
+ <div>
+ <div className="center" style={{ width: '100%' }}>
+ <img style={{ width: 350 }} src="/images/zrx_pie_chart.png" />
+ </div>
+ <div className="py1">
+ <div className="bold pb1">Token Launch (50%)</div>
+ <div>
+ ZRX is inherently a governance token that plays a critical role in the process of
+ upgrading 0x protocol. We are fully committed to formulating a functional and
+ theoretically sound governance model and we plan to dedicate significant resources to
+ R&D.
+ </div>
+ </div>
+ <div className="py1">
+ <div className="bold pb1">Retained by 0x (15%)</div>
+ <div>
+ The 0x core development team will be able to sustain itself for approximately five years
+ using funds raised through the token launch. If 0x protocol proves to be as foundational
+ a technology as we believe it to be, the retained ZRX tokens will allow the 0x core
+ development team to sustain operations beyond the first 5 years.
+ </div>
+ </div>
+ <div className="py1">
+ <div className="bold pb1">Developer Fund (15%)</div>
+ <div>
+ The Developer Fund will be used to make targeted capital injections into high potential
+ projects and teams that are attempting to grow the 0x ecosystem, strategic partnerships,
+ hackathon prizes and community development activities.
+ </div>
+ </div>
+ <div className="py1">
+ <div className="bold pb1">Founding Team (10%)</div>
+ <div>
+ The founding team’s allocation of ZRX will vest over a traditional 4 year vesting
+ schedule with a one year cliff. We believe this should be standard practice for any team
+ that is committed to making their project a long term success.
+ </div>
+ </div>
+ <div className="py1">
+ <div className="bold pb1">Early Backers & Advisors (10%)</div>
+ <div>
+ Our backers and advisors have provided capital, resources and guidance that have allowed
+ us to fill out our team, setup a robust legal entity and build a fully functional
+ product before launching a token. As a result, we have a proven track record and can
+ offer a token that holds genuine utility.
+ </div>
+ </div>
+ </div>
+ ),
+ },
+ {
+ prompt: 'Can I mine ZRX tokens?',
+ answer: (
+ <div>
+ No, the total supply of ZRX tokens is fixed and there is no continuous issuance model. Users
+ that facilitate trading over 0x protocol by operating a Relayer earn transaction fees
+ denominated in ZRX; as more trading activity is generated, more transaction fees are earned.
+ </div>
+ ),
+ },
+ {
+ prompt: 'Will there be a lockup period for ZRX tokens sold in the token launch?',
+ answer: <div>No, ZRX tokens sold in the token launch will immediately be liquid.</div>,
+ },
+ {
+ prompt: 'Will there be a lockup period for tokens allocated to the founding team?',
+ answer: (
+ <div>
+ Yes. ZRX tokens allocated to founders, advisors and staff members will be released over a 4 year
+ vesting schedule with a 25% cliff upon completion of the initial token launch and 25% released
+ each subsequent year in monthly installments. Staff members hired after the token launch will
+ have a 4 year vesting schedule with a one year cliff.
+ </div>
+ ),
+ },
+ {
+ prompt: 'Which cryptocurrencies will be accepted in the token launch?',
+ answer: <div>ETH.</div>,
+ },
+ {
+ prompt: 'When will 0x be live?',
+ answer: (
+ <div>
+ An alpha version of 0x has been live on our private test network since January 2017. Version 1.0
+ of 0x protocol will be deployed to the canonical Ethereum blockchain after a round of security
+ audits and prior to the public token launch. 0x will be using the 0x protocol during our token
+ launch.
+ </div>
+ ),
+ },
+ {
+ prompt: 'Where can I find a development roadmap?',
+ answer: (
+ <div>
+ Check it out{' '}
+ <a
+ href="https://drive.google.com/open?id=14IP1N8mt3YdsAoqYTyruMnZswpklUs3THyS1VXx71fo"
+ target="_blank"
+ >
+ here
+ </a>.
+ </div>
+ ),
+ },
+ ],
+ },
+ {
+ name: 'Team',
+ questions: [
+ {
+ prompt: 'Where is 0x based?',
+ answer: <div>0x was founded in SF and is driven by a diverse group of contributors.</div>,
+ },
+ {
+ prompt: 'How can I get involved?',
+ answer: (
+ <div>
+ Join our{' '}
+ <a href={constants.URL_ZEROEX_CHAT} target="_blank">
+ Rocket.chat
+ </a>! As an open source project, 0x will rely on a worldwide community of passionate developers
+ to contribute proposals, ideas and code.
+ </div>
+ ),
+ },
+ {
+ prompt: 'Why the name 0x?',
+ answer: (
+ <div>
+ 0x is the prefix for hexadecimal numeric constants including Ethereum addresses. In a more
+ abstract context, as the first open protocol for exchange 0x represents the beginning of the end
+ for the exchange industry’s rent seeking oligopoly: zero exchange.
+ </div>
+ ),
+ },
+ {
+ prompt: 'How do you pronounce 0x?',
+ answer: <div>We pronounce 0x as “zero-ex,” but you are free to pronounce it however you please.</div>,
+ },
+ ],
+ },
];
export class FAQ extends React.Component<FAQProps, FAQState> {
- public componentDidMount() {
- window.scrollTo(0, 0);
- }
- public render() {
- return (
- <div>
- <DocumentTitle title="0x FAQ" />
- <TopBar blockchainIsLoaded={false} location={this.props.location} />
- <div id="faq" className="mx-auto max-width-4 pt4" style={{ color: colors.grey800 }}>
- <h1 className="center" style={{ ...styles.thin }}>
- 0x FAQ
- </h1>
- <div className="sm-px2 md-px2 lg-px0 pb4">{this._renderSections()}</div>
- </div>
- <Footer />
- </div>
- );
- }
- private _renderSections() {
- const renderedSections = _.map(sections, (section: FAQSection, i: number) => {
- const isFirstSection = i === 0;
- return (
- <div key={section.name}>
- <h3>{section.name}</h3>
- {this._renderQuestions(section.questions, isFirstSection)}
- </div>
- );
- });
- return renderedSections;
- }
- private _renderQuestions(questions: FAQQuestion[], isFirstSection: boolean) {
- const renderedQuestions = _.map(questions, (question: FAQQuestion, i: number) => {
- const isFirstQuestion = i === 0;
- return (
- <Question
- key={question.prompt}
- prompt={question.prompt}
- answer={question.answer}
- shouldDisplayExpanded={isFirstSection && isFirstQuestion}
- />
- );
- });
- return renderedQuestions;
- }
+ public componentDidMount() {
+ window.scrollTo(0, 0);
+ }
+ public render() {
+ return (
+ <div>
+ <DocumentTitle title="0x FAQ" />
+ <TopBar blockchainIsLoaded={false} location={this.props.location} />
+ <div id="faq" className="mx-auto max-width-4 pt4" style={{ color: colors.grey800 }}>
+ <h1 className="center" style={{ ...styles.thin }}>
+ 0x FAQ
+ </h1>
+ <div className="sm-px2 md-px2 lg-px0 pb4">{this._renderSections()}</div>
+ </div>
+ <Footer />
+ </div>
+ );
+ }
+ private _renderSections() {
+ const renderedSections = _.map(sections, (section: FAQSection, i: number) => {
+ const isFirstSection = i === 0;
+ return (
+ <div key={section.name}>
+ <h3>{section.name}</h3>
+ {this._renderQuestions(section.questions, isFirstSection)}
+ </div>
+ );
+ });
+ return renderedSections;
+ }
+ private _renderQuestions(questions: FAQQuestion[], isFirstSection: boolean) {
+ const renderedQuestions = _.map(questions, (question: FAQQuestion, i: number) => {
+ const isFirstQuestion = i === 0;
+ return (
+ <Question
+ key={question.prompt}
+ prompt={question.prompt}
+ answer={question.answer}
+ shouldDisplayExpanded={isFirstSection && isFirstQuestion}
+ />
+ );
+ });
+ return renderedQuestions;
+ }
}
diff --git a/packages/website/ts/pages/faq/question.tsx b/packages/website/ts/pages/faq/question.tsx
index 58cf674ef..988c04bc9 100644
--- a/packages/website/ts/pages/faq/question.tsx
+++ b/packages/website/ts/pages/faq/question.tsx
@@ -4,48 +4,48 @@ import * as React from 'react';
import { colors } from 'ts/utils/colors';
export interface QuestionProps {
- prompt: string;
- answer: React.ReactNode;
- shouldDisplayExpanded: boolean;
+ prompt: string;
+ answer: React.ReactNode;
+ shouldDisplayExpanded: boolean;
}
interface QuestionState {
- isExpanded: boolean;
+ isExpanded: boolean;
}
export class Question extends React.Component<QuestionProps, QuestionState> {
- constructor(props: QuestionProps) {
- super(props);
- this.state = {
- isExpanded: props.shouldDisplayExpanded,
- };
- }
- public render() {
- return (
- <div className="py1">
- <Card
- initiallyExpanded={this.props.shouldDisplayExpanded}
- onExpandChange={this._onExchangeChange.bind(this)}
- >
- <CardHeader
- title={this.props.prompt}
- style={{
- borderBottom: this.state.isExpanded ? '1px solid rgba(0, 0, 0, 0.19)' : 'none',
- }}
- titleStyle={{ color: colors.darkerGrey }}
- actAsExpander={true}
- showExpandableButton={true}
- />
- <CardText expandable={true}>
- <div style={{ lineHeight: 1.4 }}>{this.props.answer}</div>
- </CardText>
- </Card>
- </div>
- );
- }
- private _onExchangeChange() {
- this.setState({
- isExpanded: !this.state.isExpanded,
- });
- }
+ constructor(props: QuestionProps) {
+ super(props);
+ this.state = {
+ isExpanded: props.shouldDisplayExpanded,
+ };
+ }
+ public render() {
+ return (
+ <div className="py1">
+ <Card
+ initiallyExpanded={this.props.shouldDisplayExpanded}
+ onExpandChange={this._onExchangeChange.bind(this)}
+ >
+ <CardHeader
+ title={this.props.prompt}
+ style={{
+ borderBottom: this.state.isExpanded ? '1px solid rgba(0, 0, 0, 0.19)' : 'none',
+ }}
+ titleStyle={{ color: colors.darkerGrey }}
+ actAsExpander={true}
+ showExpandableButton={true}
+ />
+ <CardText expandable={true}>
+ <div style={{ lineHeight: 1.4 }}>{this.props.answer}</div>
+ </CardText>
+ </Card>
+ </div>
+ );
+ }
+ private _onExchangeChange() {
+ this.setState({
+ isExpanded: !this.state.isExpanded,
+ });
+ }
}
diff --git a/packages/website/ts/pages/landing/landing.tsx b/packages/website/ts/pages/landing/landing.tsx
index 742d94a0f..ca76497df 100644
--- a/packages/website/ts/pages/landing/landing.tsx
+++ b/packages/website/ts/pages/landing/landing.tsx
@@ -11,755 +11,755 @@ import { constants } from 'ts/utils/constants';
import { utils } from 'ts/utils/utils';
interface BoxContent {
- title: string;
- description: string;
- imageUrl: string;
- classNames: string;
+ title: string;
+ description: string;
+ imageUrl: string;
+ classNames: string;
}
interface AssetType {
- title: string;
- imageUrl: string;
- style?: React.CSSProperties;
+ title: string;
+ imageUrl: string;
+ style?: React.CSSProperties;
}
interface UseCase {
- imageUrl: string;
- type: string;
- description: string;
- classNames: string;
- style?: React.CSSProperties;
- projectIconUrls: string[];
+ imageUrl: string;
+ type: string;
+ description: string;
+ classNames: string;
+ style?: React.CSSProperties;
+ projectIconUrls: string[];
}
interface Project {
- logoFileName: string;
- projectUrl: string;
+ logoFileName: string;
+ projectUrl: string;
}
const THROTTLE_TIMEOUT = 100;
const boxContents: BoxContent[] = [
- {
- title: 'Trustless exchange',
- description:
- "Built on Ethereum's distributed network with no centralized \
+ {
+ title: 'Trustless exchange',
+ description:
+ "Built on Ethereum's distributed network with no centralized \
point of failure and no down time, each trade is settled atomically \
and without counterparty risk.",
- imageUrl: '/images/landing/distributed_network.png',
- classNames: '',
- },
- {
- title: 'Shared liquidity',
- description:
- 'By sharing a standard API, relayers can easily aggregate liquidity pools, \
+ imageUrl: '/images/landing/distributed_network.png',
+ classNames: '',
+ },
+ {
+ title: 'Shared liquidity',
+ description:
+ 'By sharing a standard API, relayers can easily aggregate liquidity pools, \
creating network effects around liquidity that compound as more relayers come online.',
- imageUrl: '/images/landing/liquidity.png',
- classNames: 'mx-auto',
- },
- {
- title: 'Open source',
- description:
- '0x is open source, permissionless and free to use. Trade directly with a known \
+ imageUrl: '/images/landing/liquidity.png',
+ classNames: 'mx-auto',
+ },
+ {
+ title: 'Open source',
+ description:
+ '0x is open source, permissionless and free to use. Trade directly with a known \
counterparty for free or pay a relayer some ZRX tokens to access their liquidity \
pool.',
- imageUrl: '/images/landing/open_source.png',
- classNames: 'right',
- },
+ imageUrl: '/images/landing/open_source.png',
+ classNames: 'right',
+ },
];
const projects: Project[] = [
- {
- logoFileName: 'ethfinex-top.png',
- projectUrl: constants.PROJECT_URL_ETHFINEX,
- },
- {
- logoFileName: 'radar_relay_top.png',
- projectUrl: constants.PROJECT_URL_RADAR_RELAY,
- },
- {
- logoFileName: 'paradex_top.png',
- projectUrl: constants.PROJECT_URL_PARADEX,
- },
- {
- logoFileName: 'the_ocean.png',
- projectUrl: constants.PROJECT_URL_0CEAN,
- },
- {
- logoFileName: 'dydx.png',
- projectUrl: constants.PROJECT_URL_DYDX,
- },
- {
- logoFileName: 'melonport.png',
- projectUrl: constants.PROJECT_URL_MELONPORT,
- },
- {
- logoFileName: 'maker.png',
- projectUrl: constants.PROJECT_URL_MAKER,
- },
- {
- logoFileName: 'dharma.png',
- projectUrl: constants.PROJECT_URL_DHARMA,
- },
- {
- logoFileName: 'lendroid.png',
- projectUrl: constants.PROJECT_URL_LENDROID,
- },
- {
- logoFileName: 'district0x.png',
- projectUrl: constants.PROJECT_URL_DISTRICT_0X,
- },
- {
- logoFileName: 'aragon.png',
- projectUrl: constants.PROJECT_URL_ARAGON,
- },
- {
- logoFileName: 'blocknet.png',
- projectUrl: constants.PROJECT_URL_BLOCKNET,
- },
- {
- logoFileName: 'status.png',
- projectUrl: constants.PROJECT_URL_STATUS,
- },
- {
- logoFileName: 'augur.png',
- projectUrl: constants.PROJECT_URL_AUGUR,
- },
- {
- logoFileName: 'anx.png',
- projectUrl: constants.PROJECT_URL_OPEN_ANX,
- },
- {
- logoFileName: 'auctus.png',
- projectUrl: constants.PROJECT_URL_AUCTUS,
- },
+ {
+ logoFileName: 'ethfinex-top.png',
+ projectUrl: constants.PROJECT_URL_ETHFINEX,
+ },
+ {
+ logoFileName: 'radar_relay_top.png',
+ projectUrl: constants.PROJECT_URL_RADAR_RELAY,
+ },
+ {
+ logoFileName: 'paradex_top.png',
+ projectUrl: constants.PROJECT_URL_PARADEX,
+ },
+ {
+ logoFileName: 'the_ocean.png',
+ projectUrl: constants.PROJECT_URL_0CEAN,
+ },
+ {
+ logoFileName: 'dydx.png',
+ projectUrl: constants.PROJECT_URL_DYDX,
+ },
+ {
+ logoFileName: 'melonport.png',
+ projectUrl: constants.PROJECT_URL_MELONPORT,
+ },
+ {
+ logoFileName: 'maker.png',
+ projectUrl: constants.PROJECT_URL_MAKER,
+ },
+ {
+ logoFileName: 'dharma.png',
+ projectUrl: constants.PROJECT_URL_DHARMA,
+ },
+ {
+ logoFileName: 'lendroid.png',
+ projectUrl: constants.PROJECT_URL_LENDROID,
+ },
+ {
+ logoFileName: 'district0x.png',
+ projectUrl: constants.PROJECT_URL_DISTRICT_0X,
+ },
+ {
+ logoFileName: 'aragon.png',
+ projectUrl: constants.PROJECT_URL_ARAGON,
+ },
+ {
+ logoFileName: 'blocknet.png',
+ projectUrl: constants.PROJECT_URL_BLOCKNET,
+ },
+ {
+ logoFileName: 'status.png',
+ projectUrl: constants.PROJECT_URL_STATUS,
+ },
+ {
+ logoFileName: 'augur.png',
+ projectUrl: constants.PROJECT_URL_AUGUR,
+ },
+ {
+ logoFileName: 'anx.png',
+ projectUrl: constants.PROJECT_URL_OPEN_ANX,
+ },
+ {
+ logoFileName: 'auctus.png',
+ projectUrl: constants.PROJECT_URL_AUCTUS,
+ },
];
export interface LandingProps {
- location: Location;
+ location: Location;
}
interface LandingState {
- screenWidth: ScreenWidths;
+ screenWidth: ScreenWidths;
}
export class Landing extends React.Component<LandingProps, LandingState> {
- private _throttledScreenWidthUpdate: () => void;
- constructor(props: LandingProps) {
- super(props);
- this.state = {
- screenWidth: utils.getScreenWidth(),
- };
- this._throttledScreenWidthUpdate = _.throttle(this._updateScreenWidth.bind(this), THROTTLE_TIMEOUT);
- }
- public componentDidMount() {
- window.addEventListener('resize', this._throttledScreenWidthUpdate);
- window.scrollTo(0, 0);
- }
- public componentWillUnmount() {
- window.removeEventListener('resize', this._throttledScreenWidthUpdate);
- }
- public render() {
- return (
- <div id="landing" className="clearfix" style={{ color: colors.grey500 }}>
- <DocumentTitle title="0x Protocol" />
- <TopBar
- blockchainIsLoaded={false}
- location={this.props.location}
- isNightVersion={true}
- style={{ backgroundColor: colors.heroGrey, position: 'relative' }}
- />
- {this._renderHero()}
- {this._renderProjects()}
- {this._renderTokenizationSection()}
- {this._renderProtocolSection()}
- {this._renderInfoBoxes()}
- {this._renderBuildingBlocksSection()}
- {this._renderUseCases()}
- {this._renderCallToAction()}
- <Footer />
- </div>
- );
- }
- private _renderHero() {
- const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm;
- const buttonLabelStyle: React.CSSProperties = {
- textTransform: 'none',
- fontSize: isSmallScreen ? 12 : 14,
- fontWeight: 400,
- };
- const lightButtonStyle: React.CSSProperties = {
- borderRadius: 6,
- border: '1px solid #D8D8D8',
- lineHeight: '33px',
- height: 38,
- };
- const left = 'col lg-col-7 md-col-7 col-12 lg-pt4 md-pt4 sm-pt0 mt1 lg-pl4 md-pl4 sm-pl0 sm-px3 sm-center';
- return (
- <div className="clearfix py4" style={{ backgroundColor: colors.heroGrey }}>
- <div className="mx-auto max-width-4 clearfix">
- <div className="lg-pt4 md-pt4 sm-pt2 lg-pb4 md-pb4 lg-my4 md-my4 sm-mt2 sm-mb4 clearfix">
- <div className="col lg-col-5 md-col-5 col-12 sm-center">
- <img src="/images/landing/hero_chip_image.png" height={isSmallScreen ? 300 : 395} />
- </div>
- <div className={left} style={{ color: colors.white }}>
- <div style={{ paddingLeft: isSmallScreen ? 0 : 12 }}>
- <div
- className="sm-pb2"
- style={{
- fontFamily: 'Roboto Mono',
- fontSize: isSmallScreen ? 26 : 34,
- }}
- >
- Powering decentralized exchange
- </div>
- <div
- className="pt2 h5 sm-mx-auto"
- style={{
- maxWidth: 446,
- fontFamily: 'Roboto Mono',
- lineHeight: 1.7,
- fontWeight: 300,
- }}
- >
- 0x is an open, permissionless protocol allowing for ERC20 tokens to be traded on the
- Ethereum blockchain.
- </div>
- <div className="pt3 clearfix sm-mx-auto" style={{ maxWidth: 342 }}>
- <div className="lg-pr2 md-pr2 col col-6 sm-center">
- <Link to={WebsitePaths.ZeroExJs} className="text-decoration-none">
- <RaisedButton
- style={{ borderRadius: 6, minWidth: 157.36 }}
- buttonStyle={{ borderRadius: 6 }}
- labelStyle={buttonLabelStyle}
- label="Build on 0x"
- onClick={_.noop}
- />
- </Link>
- </div>
- <div className="col col-6 sm-center">
- <a
- href={constants.URL_ZEROEX_CHAT}
- target="_blank"
- className="text-decoration-none"
- >
- <RaisedButton
- style={{ borderRadius: 6, minWidth: 150 }}
- buttonStyle={lightButtonStyle}
- labelColor="white"
- backgroundColor={colors.heroGrey}
- labelStyle={buttonLabelStyle}
- label="Join the community"
- onClick={_.noop}
- />
- </a>
- </div>
- </div>
- </div>
- </div>
- </div>
- </div>
- </div>
- );
- }
- private _renderProjects() {
- const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm;
- const isMediumScreen = this.state.screenWidth === ScreenWidths.Md;
- const projectList = _.map(projects, (project: Project, i: number) => {
- const colWidth = isSmallScreen ? 3 : isMediumScreen ? 4 : 2 - i % 2;
- return (
- <div key={`project-${project.logoFileName}`} className={`col col-${colWidth} center`}>
- <div>
- <a href={project.projectUrl} target="_blank" className="text-decoration-none">
- <img
- src={`/images/landing/project_logos/${project.logoFileName}`}
- height={isSmallScreen ? 60 : 92}
- />
- </a>
- </div>
- </div>
- );
- });
- const titleStyle: React.CSSProperties = {
- fontFamily: 'Roboto Mono',
- color: colors.grey,
- textTransform: 'uppercase',
- fontWeight: 300,
- letterSpacing: 3,
- };
- return (
- <div className="clearfix py4" style={{ backgroundColor: colors.projectsGrey }}>
- <div className="mx-auto max-width-4 clearfix sm-px3">
- <div className="h4 pb3 md-pl3 sm-pl2" style={titleStyle}>
- Projects building on 0x
- </div>
- <div className="clearfix">{projectList}</div>
- <div
- className="pt3 mx-auto center"
- style={{
- color: colors.landingLinkGrey,
- fontFamily: 'Roboto Mono',
- maxWidth: 300,
- fontSize: 14,
- }}
- >
- view the{' '}
- <Link
- to={`${WebsitePaths.Wiki}#List-of-Projects-Using-0x-Protocol`}
- className="text-decoration-none underline"
- style={{ color: colors.landingLinkGrey }}
- >
- full list
- </Link>
- </div>
- </div>
- </div>
- );
- }
- private _renderTokenizationSection() {
- const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm;
- return (
- <div className="clearfix lg-py4 md-py4 sm-pb4 sm-pt2" style={{ backgroundColor: colors.grey100 }}>
- <div className="mx-auto max-width-4 py4 clearfix">
- {isSmallScreen && this._renderTokenCloud()}
- <div className="col lg-col-6 md-col-6 col-12">
- <div className="mx-auto" style={{ maxWidth: 385, paddingTop: 7 }}>
- <div className="lg-h1 md-h1 sm-h2 sm-center sm-pt3" style={{ fontFamily: 'Roboto Mono' }}>
- The world's value is becoming tokenized
- </div>
- <div
- className="pb2 lg-pt2 md-pt2 sm-pt3 sm-px3 h5 sm-center"
- style={{ fontFamily: 'Roboto Mono', lineHeight: 1.7 }}
- >
- {isSmallScreen ? (
- <span>
- The Ethereum blockchain is an open, borderless financial system that represents
- a wide variety of assets as cryptographic tokens. In the future, most digital
- assets and goods will be tokenized.
- </span>
- ) : (
- <div>
- <div>
- The Ethereum blockchain is an open, borderless financial system that
- represents
- </div>
- <div>
- a wide variety of assets as cryptographic tokens. In the future, most
- digital assets and goods will be tokenized.
- </div>
- </div>
- )}
- </div>
- <div className="flex pt1 sm-px3">{this._renderAssetTypes()}</div>
- </div>
- </div>
- {!isSmallScreen && this._renderTokenCloud()}
- </div>
- </div>
- );
- }
- private _renderProtocolSection() {
- const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm;
- return (
- <div className="clearfix lg-py4 md-py4 sm-pt4" style={{ backgroundColor: colors.heroGrey }}>
- <div className="mx-auto max-width-4 lg-py4 md-py4 sm-pt4 clearfix">
- <div className="col lg-col-6 md-col-6 col-12 sm-center">
- <img src="/images/landing/relayer_diagram.png" height={isSmallScreen ? 326 : 426} />
- </div>
- <div
- className="col lg-col-6 md-col-6 col-12 lg-pr3 md-pr3 sm-mx-auto"
- style={{
- color: colors.beigeWhite,
- paddingTop: 8,
- maxWidth: isSmallScreen ? 'none' : 445,
- }}
- >
- <div className="lg-h1 md-h1 sm-h2 pb1 sm-pt3 sm-center" style={{ fontFamily: 'Roboto Mono' }}>
- <div>Off-chain order relay</div>
- <div>On-chain settlement</div>
- </div>
- <div
- className="pb2 pt2 h5 sm-center sm-px3 sm-mx-auto"
- style={{
- fontFamily: 'Roboto Mono',
- lineHeight: 1.7,
- fontWeight: 300,
- maxWidth: 445,
- }}
- >
- In 0x protocol, orders are transported off-chain, massively reducing gas costs and
- eliminating blockchain bloat. Relayers help broadcast orders and collect a fee each time
- they facilitate a trade. Anyone can build a relayer.
- </div>
- <div
- className="pt3 sm-mx-auto sm-px3"
- style={{
- color: colors.landingLinkGrey,
- maxWidth: isSmallScreen ? 412 : 'none',
- }}
- >
- <div className="flex" style={{ fontSize: 18 }}>
- <div
- className="lg-h4 md-h4 sm-h5"
- style={{
- letterSpacing: isSmallScreen ? 1 : 3,
- fontFamily: 'Roboto Mono',
- }}
- >
- RELAYERS BUILDING ON 0X
- </div>
- <div className="h5" style={{ marginLeft: isSmallScreen ? 26 : 49 }}>
- <Link
- to={`${WebsitePaths.Wiki}#List-of-Projects-Using-0x-Protocol`}
- className="text-decoration-none underline"
- style={{
- color: colors.landingLinkGrey,
- fontFamily: 'Roboto Mono',
- }}
- >
- view all
- </Link>
- </div>
- </div>
- <div className="lg-flex md-flex sm-clearfix pt3" style={{ opacity: 0.4 }}>
- <div className="col col-4 sm-center">
- <img
- src="/images/landing/ethfinex.png"
- style={{ height: isSmallScreen ? 85 : 107 }}
- />
- </div>
- <div className="col col-4 center">
- <img
- src="/images/landing/radar_relay.png"
- style={{ height: isSmallScreen ? 85 : 107 }}
- />
- </div>
- <div className="col col-4 sm-center" style={{ textAlign: 'right' }}>
- <img
- src="/images/landing/paradex.png"
- style={{ height: isSmallScreen ? 85 : 107 }}
- />
- </div>
- </div>
- </div>
- </div>
- </div>
- </div>
- );
- }
- private _renderBuildingBlocksSection() {
- const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm;
- const descriptionStyle: React.CSSProperties = {
- fontFamily: 'Roboto Mono',
- lineHeight: isSmallScreen ? 1.5 : 2,
- fontWeight: 300,
- fontSize: 15,
- maxWidth: isSmallScreen ? 375 : 'none',
- };
- const callToActionStyle: React.CSSProperties = {
- fontFamily: 'Roboto Mono',
- fontSize: 15,
- fontWeight: 300,
- maxWidth: isSmallScreen ? 375 : 441,
- };
- return (
- <div className="clearfix lg-pt4 md-pt4" style={{ backgroundColor: colors.heroGrey }}>
- <div className="mx-auto max-width-4 lg-pt4 md-pt4 lg-mb4 md-mb4 sm-mb2 clearfix">
- {isSmallScreen && this._renderBlockChipImage()}
- <div
- className="col lg-col-6 md-col-6 col-12 lg-pr3 md-pr3 sm-px3"
- style={{ color: colors.beigeWhite }}
- >
- <div
- className="pb1 lg-pt4 md-pt4 sm-pt3 lg-h1 md-h1 sm-h2 sm-px3 sm-center"
- style={{ fontFamily: 'Roboto Mono' }}
- >
- A building block for dApps
- </div>
- <div className="pb3 pt2 sm-mx-auto sm-center" style={descriptionStyle}>
- 0x protocol is a pluggable building block for dApps that require exchange functionality.
- Join the many developers that are already using 0x in their web applications and smart
- contracts.
- </div>
- <div className="sm-mx-auto sm-center" style={callToActionStyle}>
- Learn how in our{' '}
- <Link
- to={WebsitePaths.ZeroExJs}
- className="text-decoration-none underline"
- style={{ color: colors.beigeWhite, fontFamily: 'Roboto Mono' }}
- >
- 0x.js
- </Link>{' '}
- and{' '}
- <Link
- to={WebsitePaths.SmartContracts}
- className="text-decoration-none underline"
- style={{ color: colors.beigeWhite, fontFamily: 'Roboto Mono' }}
- >
- smart contract
- </Link>{' '}
- docs
- </div>
- </div>
- {!isSmallScreen && this._renderBlockChipImage()}
- </div>
- </div>
- );
- }
- private _renderBlockChipImage() {
- const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm;
- return (
- <div className="col lg-col-6 md-col-6 col-12 sm-center">
- <img src="/images/landing/0x_chips.png" height={isSmallScreen ? 240 : 368} />
- </div>
- );
- }
- private _renderTokenCloud() {
- const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm;
- return (
- <div className="col lg-col-6 md-col-6 col-12 center">
- <img src="/images/landing/tokenized_world.png" height={isSmallScreen ? 280 : 364.5} />
- </div>
- );
- }
- private _renderAssetTypes() {
- const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm;
- const assetTypes: AssetType[] = [
- {
- title: 'Currency',
- imageUrl: '/images/landing/currency.png',
- },
- {
- title: 'Traditional assets',
- imageUrl: '/images/landing/stocks.png',
- style: {
- paddingLeft: isSmallScreen ? 41 : 56,
- paddingRight: isSmallScreen ? 41 : 56,
- },
- },
- {
- title: 'Digital goods',
- imageUrl: '/images/landing/digital_goods.png',
- },
- ];
- const assets = _.map(assetTypes, (assetType: AssetType) => {
- const style = _.isUndefined(assetType.style) ? {} : assetType.style;
- return (
- <div key={`asset-${assetType.title}`} className="center" style={{ opacity: 0.8, ...style }}>
- <div>
- <img src={assetType.imageUrl} height="80" />
- </div>
- <div
- style={{
- fontFamily: 'Roboto Mono',
- fontSize: 13.5,
- fontWeight: 400,
- opacity: 0.75,
- }}
- >
- {assetType.title}
- </div>
- </div>
- );
- });
- return assets;
- }
- private _renderInfoBoxes() {
- const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm;
- const boxStyle: React.CSSProperties = {
- maxWidth: 252,
- height: 386,
- backgroundColor: colors.grey50,
- borderRadius: 5,
- padding: '10px 24px 24px',
- };
- const boxes = _.map(boxContents, (boxContent: BoxContent) => {
- return (
- <div key={`box-${boxContent.title}`} className="col lg-col-4 md-col-4 col-12 sm-pb4">
- <div className={`center sm-mx-auto ${!isSmallScreen && boxContent.classNames}`} style={boxStyle}>
- <div>
- <img src={boxContent.imageUrl} style={{ height: 210 }} />
- </div>
- <div className="h3" style={{ color: 'black', fontFamily: 'Roboto Mono' }}>
- {boxContent.title}
- </div>
- <div className="pt2 pb2" style={{ fontFamily: 'Roboto Mono', fontSize: 14 }}>
- {boxContent.description}
- </div>
- </div>
- </div>
- );
- });
- return (
- <div className="clearfix" style={{ backgroundColor: colors.heroGrey }}>
- <div className="mx-auto py4 sm-mt2 clearfix" style={{ maxWidth: '60em' }}>
- {boxes}
- </div>
- </div>
- );
- }
- private _renderUseCases() {
- const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm;
+ private _throttledScreenWidthUpdate: () => void;
+ constructor(props: LandingProps) {
+ super(props);
+ this.state = {
+ screenWidth: utils.getScreenWidth(),
+ };
+ this._throttledScreenWidthUpdate = _.throttle(this._updateScreenWidth.bind(this), THROTTLE_TIMEOUT);
+ }
+ public componentDidMount() {
+ window.addEventListener('resize', this._throttledScreenWidthUpdate);
+ window.scrollTo(0, 0);
+ }
+ public componentWillUnmount() {
+ window.removeEventListener('resize', this._throttledScreenWidthUpdate);
+ }
+ public render() {
+ return (
+ <div id="landing" className="clearfix" style={{ color: colors.grey500 }}>
+ <DocumentTitle title="0x Protocol" />
+ <TopBar
+ blockchainIsLoaded={false}
+ location={this.props.location}
+ isNightVersion={true}
+ style={{ backgroundColor: colors.heroGrey, position: 'relative' }}
+ />
+ {this._renderHero()}
+ {this._renderProjects()}
+ {this._renderTokenizationSection()}
+ {this._renderProtocolSection()}
+ {this._renderInfoBoxes()}
+ {this._renderBuildingBlocksSection()}
+ {this._renderUseCases()}
+ {this._renderCallToAction()}
+ <Footer />
+ </div>
+ );
+ }
+ private _renderHero() {
+ const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm;
+ const buttonLabelStyle: React.CSSProperties = {
+ textTransform: 'none',
+ fontSize: isSmallScreen ? 12 : 14,
+ fontWeight: 400,
+ };
+ const lightButtonStyle: React.CSSProperties = {
+ borderRadius: 6,
+ border: '1px solid #D8D8D8',
+ lineHeight: '33px',
+ height: 38,
+ };
+ const left = 'col lg-col-7 md-col-7 col-12 lg-pt4 md-pt4 sm-pt0 mt1 lg-pl4 md-pl4 sm-pl0 sm-px3 sm-center';
+ return (
+ <div className="clearfix py4" style={{ backgroundColor: colors.heroGrey }}>
+ <div className="mx-auto max-width-4 clearfix">
+ <div className="lg-pt4 md-pt4 sm-pt2 lg-pb4 md-pb4 lg-my4 md-my4 sm-mt2 sm-mb4 clearfix">
+ <div className="col lg-col-5 md-col-5 col-12 sm-center">
+ <img src="/images/landing/hero_chip_image.png" height={isSmallScreen ? 300 : 395} />
+ </div>
+ <div className={left} style={{ color: colors.white }}>
+ <div style={{ paddingLeft: isSmallScreen ? 0 : 12 }}>
+ <div
+ className="sm-pb2"
+ style={{
+ fontFamily: 'Roboto Mono',
+ fontSize: isSmallScreen ? 26 : 34,
+ }}
+ >
+ Powering decentralized exchange
+ </div>
+ <div
+ className="pt2 h5 sm-mx-auto"
+ style={{
+ maxWidth: 446,
+ fontFamily: 'Roboto Mono',
+ lineHeight: 1.7,
+ fontWeight: 300,
+ }}
+ >
+ 0x is an open, permissionless protocol allowing for ERC20 tokens to be traded on the
+ Ethereum blockchain.
+ </div>
+ <div className="pt3 clearfix sm-mx-auto" style={{ maxWidth: 342 }}>
+ <div className="lg-pr2 md-pr2 col col-6 sm-center">
+ <Link to={WebsitePaths.ZeroExJs} className="text-decoration-none">
+ <RaisedButton
+ style={{ borderRadius: 6, minWidth: 157.36 }}
+ buttonStyle={{ borderRadius: 6 }}
+ labelStyle={buttonLabelStyle}
+ label="Build on 0x"
+ onClick={_.noop}
+ />
+ </Link>
+ </div>
+ <div className="col col-6 sm-center">
+ <a
+ href={constants.URL_ZEROEX_CHAT}
+ target="_blank"
+ className="text-decoration-none"
+ >
+ <RaisedButton
+ style={{ borderRadius: 6, minWidth: 150 }}
+ buttonStyle={lightButtonStyle}
+ labelColor="white"
+ backgroundColor={colors.heroGrey}
+ labelStyle={buttonLabelStyle}
+ label="Join the community"
+ onClick={_.noop}
+ />
+ </a>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ );
+ }
+ private _renderProjects() {
+ const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm;
+ const isMediumScreen = this.state.screenWidth === ScreenWidths.Md;
+ const projectList = _.map(projects, (project: Project, i: number) => {
+ const colWidth = isSmallScreen ? 3 : isMediumScreen ? 4 : 2 - i % 2;
+ return (
+ <div key={`project-${project.logoFileName}`} className={`col col-${colWidth} center`}>
+ <div>
+ <a href={project.projectUrl} target="_blank" className="text-decoration-none">
+ <img
+ src={`/images/landing/project_logos/${project.logoFileName}`}
+ height={isSmallScreen ? 60 : 92}
+ />
+ </a>
+ </div>
+ </div>
+ );
+ });
+ const titleStyle: React.CSSProperties = {
+ fontFamily: 'Roboto Mono',
+ color: colors.grey,
+ textTransform: 'uppercase',
+ fontWeight: 300,
+ letterSpacing: 3,
+ };
+ return (
+ <div className="clearfix py4" style={{ backgroundColor: colors.projectsGrey }}>
+ <div className="mx-auto max-width-4 clearfix sm-px3">
+ <div className="h4 pb3 md-pl3 sm-pl2" style={titleStyle}>
+ Projects building on 0x
+ </div>
+ <div className="clearfix">{projectList}</div>
+ <div
+ className="pt3 mx-auto center"
+ style={{
+ color: colors.landingLinkGrey,
+ fontFamily: 'Roboto Mono',
+ maxWidth: 300,
+ fontSize: 14,
+ }}
+ >
+ view the{' '}
+ <Link
+ to={`${WebsitePaths.Wiki}#List-of-Projects-Using-0x-Protocol`}
+ className="text-decoration-none underline"
+ style={{ color: colors.landingLinkGrey }}
+ >
+ full list
+ </Link>
+ </div>
+ </div>
+ </div>
+ );
+ }
+ private _renderTokenizationSection() {
+ const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm;
+ return (
+ <div className="clearfix lg-py4 md-py4 sm-pb4 sm-pt2" style={{ backgroundColor: colors.grey100 }}>
+ <div className="mx-auto max-width-4 py4 clearfix">
+ {isSmallScreen && this._renderTokenCloud()}
+ <div className="col lg-col-6 md-col-6 col-12">
+ <div className="mx-auto" style={{ maxWidth: 385, paddingTop: 7 }}>
+ <div className="lg-h1 md-h1 sm-h2 sm-center sm-pt3" style={{ fontFamily: 'Roboto Mono' }}>
+ The world's value is becoming tokenized
+ </div>
+ <div
+ className="pb2 lg-pt2 md-pt2 sm-pt3 sm-px3 h5 sm-center"
+ style={{ fontFamily: 'Roboto Mono', lineHeight: 1.7 }}
+ >
+ {isSmallScreen ? (
+ <span>
+ The Ethereum blockchain is an open, borderless financial system that represents
+ a wide variety of assets as cryptographic tokens. In the future, most digital
+ assets and goods will be tokenized.
+ </span>
+ ) : (
+ <div>
+ <div>
+ The Ethereum blockchain is an open, borderless financial system that
+ represents
+ </div>
+ <div>
+ a wide variety of assets as cryptographic tokens. In the future, most
+ digital assets and goods will be tokenized.
+ </div>
+ </div>
+ )}
+ </div>
+ <div className="flex pt1 sm-px3">{this._renderAssetTypes()}</div>
+ </div>
+ </div>
+ {!isSmallScreen && this._renderTokenCloud()}
+ </div>
+ </div>
+ );
+ }
+ private _renderProtocolSection() {
+ const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm;
+ return (
+ <div className="clearfix lg-py4 md-py4 sm-pt4" style={{ backgroundColor: colors.heroGrey }}>
+ <div className="mx-auto max-width-4 lg-py4 md-py4 sm-pt4 clearfix">
+ <div className="col lg-col-6 md-col-6 col-12 sm-center">
+ <img src="/images/landing/relayer_diagram.png" height={isSmallScreen ? 326 : 426} />
+ </div>
+ <div
+ className="col lg-col-6 md-col-6 col-12 lg-pr3 md-pr3 sm-mx-auto"
+ style={{
+ color: colors.beigeWhite,
+ paddingTop: 8,
+ maxWidth: isSmallScreen ? 'none' : 445,
+ }}
+ >
+ <div className="lg-h1 md-h1 sm-h2 pb1 sm-pt3 sm-center" style={{ fontFamily: 'Roboto Mono' }}>
+ <div>Off-chain order relay</div>
+ <div>On-chain settlement</div>
+ </div>
+ <div
+ className="pb2 pt2 h5 sm-center sm-px3 sm-mx-auto"
+ style={{
+ fontFamily: 'Roboto Mono',
+ lineHeight: 1.7,
+ fontWeight: 300,
+ maxWidth: 445,
+ }}
+ >
+ In 0x protocol, orders are transported off-chain, massively reducing gas costs and
+ eliminating blockchain bloat. Relayers help broadcast orders and collect a fee each time
+ they facilitate a trade. Anyone can build a relayer.
+ </div>
+ <div
+ className="pt3 sm-mx-auto sm-px3"
+ style={{
+ color: colors.landingLinkGrey,
+ maxWidth: isSmallScreen ? 412 : 'none',
+ }}
+ >
+ <div className="flex" style={{ fontSize: 18 }}>
+ <div
+ className="lg-h4 md-h4 sm-h5"
+ style={{
+ letterSpacing: isSmallScreen ? 1 : 3,
+ fontFamily: 'Roboto Mono',
+ }}
+ >
+ RELAYERS BUILDING ON 0X
+ </div>
+ <div className="h5" style={{ marginLeft: isSmallScreen ? 26 : 49 }}>
+ <Link
+ to={`${WebsitePaths.Wiki}#List-of-Projects-Using-0x-Protocol`}
+ className="text-decoration-none underline"
+ style={{
+ color: colors.landingLinkGrey,
+ fontFamily: 'Roboto Mono',
+ }}
+ >
+ view all
+ </Link>
+ </div>
+ </div>
+ <div className="lg-flex md-flex sm-clearfix pt3" style={{ opacity: 0.4 }}>
+ <div className="col col-4 sm-center">
+ <img
+ src="/images/landing/ethfinex.png"
+ style={{ height: isSmallScreen ? 85 : 107 }}
+ />
+ </div>
+ <div className="col col-4 center">
+ <img
+ src="/images/landing/radar_relay.png"
+ style={{ height: isSmallScreen ? 85 : 107 }}
+ />
+ </div>
+ <div className="col col-4 sm-center" style={{ textAlign: 'right' }}>
+ <img
+ src="/images/landing/paradex.png"
+ style={{ height: isSmallScreen ? 85 : 107 }}
+ />
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ );
+ }
+ private _renderBuildingBlocksSection() {
+ const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm;
+ const descriptionStyle: React.CSSProperties = {
+ fontFamily: 'Roboto Mono',
+ lineHeight: isSmallScreen ? 1.5 : 2,
+ fontWeight: 300,
+ fontSize: 15,
+ maxWidth: isSmallScreen ? 375 : 'none',
+ };
+ const callToActionStyle: React.CSSProperties = {
+ fontFamily: 'Roboto Mono',
+ fontSize: 15,
+ fontWeight: 300,
+ maxWidth: isSmallScreen ? 375 : 441,
+ };
+ return (
+ <div className="clearfix lg-pt4 md-pt4" style={{ backgroundColor: colors.heroGrey }}>
+ <div className="mx-auto max-width-4 lg-pt4 md-pt4 lg-mb4 md-mb4 sm-mb2 clearfix">
+ {isSmallScreen && this._renderBlockChipImage()}
+ <div
+ className="col lg-col-6 md-col-6 col-12 lg-pr3 md-pr3 sm-px3"
+ style={{ color: colors.beigeWhite }}
+ >
+ <div
+ className="pb1 lg-pt4 md-pt4 sm-pt3 lg-h1 md-h1 sm-h2 sm-px3 sm-center"
+ style={{ fontFamily: 'Roboto Mono' }}
+ >
+ A building block for dApps
+ </div>
+ <div className="pb3 pt2 sm-mx-auto sm-center" style={descriptionStyle}>
+ 0x protocol is a pluggable building block for dApps that require exchange functionality.
+ Join the many developers that are already using 0x in their web applications and smart
+ contracts.
+ </div>
+ <div className="sm-mx-auto sm-center" style={callToActionStyle}>
+ Learn how in our{' '}
+ <Link
+ to={WebsitePaths.ZeroExJs}
+ className="text-decoration-none underline"
+ style={{ color: colors.beigeWhite, fontFamily: 'Roboto Mono' }}
+ >
+ 0x.js
+ </Link>{' '}
+ and{' '}
+ <Link
+ to={WebsitePaths.SmartContracts}
+ className="text-decoration-none underline"
+ style={{ color: colors.beigeWhite, fontFamily: 'Roboto Mono' }}
+ >
+ smart contract
+ </Link>{' '}
+ docs
+ </div>
+ </div>
+ {!isSmallScreen && this._renderBlockChipImage()}
+ </div>
+ </div>
+ );
+ }
+ private _renderBlockChipImage() {
+ const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm;
+ return (
+ <div className="col lg-col-6 md-col-6 col-12 sm-center">
+ <img src="/images/landing/0x_chips.png" height={isSmallScreen ? 240 : 368} />
+ </div>
+ );
+ }
+ private _renderTokenCloud() {
+ const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm;
+ return (
+ <div className="col lg-col-6 md-col-6 col-12 center">
+ <img src="/images/landing/tokenized_world.png" height={isSmallScreen ? 280 : 364.5} />
+ </div>
+ );
+ }
+ private _renderAssetTypes() {
+ const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm;
+ const assetTypes: AssetType[] = [
+ {
+ title: 'Currency',
+ imageUrl: '/images/landing/currency.png',
+ },
+ {
+ title: 'Traditional assets',
+ imageUrl: '/images/landing/stocks.png',
+ style: {
+ paddingLeft: isSmallScreen ? 41 : 56,
+ paddingRight: isSmallScreen ? 41 : 56,
+ },
+ },
+ {
+ title: 'Digital goods',
+ imageUrl: '/images/landing/digital_goods.png',
+ },
+ ];
+ const assets = _.map(assetTypes, (assetType: AssetType) => {
+ const style = _.isUndefined(assetType.style) ? {} : assetType.style;
+ return (
+ <div key={`asset-${assetType.title}`} className="center" style={{ opacity: 0.8, ...style }}>
+ <div>
+ <img src={assetType.imageUrl} height="80" />
+ </div>
+ <div
+ style={{
+ fontFamily: 'Roboto Mono',
+ fontSize: 13.5,
+ fontWeight: 400,
+ opacity: 0.75,
+ }}
+ >
+ {assetType.title}
+ </div>
+ </div>
+ );
+ });
+ return assets;
+ }
+ private _renderInfoBoxes() {
+ const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm;
+ const boxStyle: React.CSSProperties = {
+ maxWidth: 252,
+ height: 386,
+ backgroundColor: colors.grey50,
+ borderRadius: 5,
+ padding: '10px 24px 24px',
+ };
+ const boxes = _.map(boxContents, (boxContent: BoxContent) => {
+ return (
+ <div key={`box-${boxContent.title}`} className="col lg-col-4 md-col-4 col-12 sm-pb4">
+ <div className={`center sm-mx-auto ${!isSmallScreen && boxContent.classNames}`} style={boxStyle}>
+ <div>
+ <img src={boxContent.imageUrl} style={{ height: 210 }} />
+ </div>
+ <div className="h3" style={{ color: 'black', fontFamily: 'Roboto Mono' }}>
+ {boxContent.title}
+ </div>
+ <div className="pt2 pb2" style={{ fontFamily: 'Roboto Mono', fontSize: 14 }}>
+ {boxContent.description}
+ </div>
+ </div>
+ </div>
+ );
+ });
+ return (
+ <div className="clearfix" style={{ backgroundColor: colors.heroGrey }}>
+ <div className="mx-auto py4 sm-mt2 clearfix" style={{ maxWidth: '60em' }}>
+ {boxes}
+ </div>
+ </div>
+ );
+ }
+ private _renderUseCases() {
+ const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm;
- const useCases: UseCase[] = [
- {
- imageUrl: '/images/landing/governance_icon.png',
- type: 'Decentralized governance',
- description:
- 'Decentralized organizations use tokens to represent ownership and \
+ const useCases: UseCase[] = [
+ {
+ imageUrl: '/images/landing/governance_icon.png',
+ type: 'Decentralized governance',
+ description:
+ 'Decentralized organizations use tokens to represent ownership and \
guide their governance logic. 0x allows decentralized organizations \
to seamlessly and safely trade ownership for startup capital.',
- projectIconUrls: ['/images/landing/aragon.png'],
- classNames: 'lg-px2 md-px2',
- },
- {
- imageUrl: '/images/landing/prediction_market_icon.png',
- type: 'Prediction markets',
- description:
- 'Decentralized prediction market platforms generate sets of tokens that \
+ projectIconUrls: ['/images/landing/aragon.png'],
+ classNames: 'lg-px2 md-px2',
+ },
+ {
+ imageUrl: '/images/landing/prediction_market_icon.png',
+ type: 'Prediction markets',
+ description:
+ 'Decentralized prediction market platforms generate sets of tokens that \
represent a financial stake in the outcomes of real-world events. 0x allows \
these tokens to be instantly tradable.',
- projectIconUrls: ['/images/landing/augur.png'],
- classNames: 'lg-px2 md-px2',
- },
- {
- imageUrl: '/images/landing/stable_tokens_icon.png',
- type: 'Stable tokens',
- description:
- 'Novel economic constructs such as stable coins require efficient, liquid \
+ projectIconUrls: ['/images/landing/augur.png'],
+ classNames: 'lg-px2 md-px2',
+ },
+ {
+ imageUrl: '/images/landing/stable_tokens_icon.png',
+ type: 'Stable tokens',
+ description:
+ 'Novel economic constructs such as stable coins require efficient, liquid \
markets to succeed. 0x will facilitate the underlying economic mechanisms \
that allow these tokens to remain stable.',
- projectIconUrls: ['/images/landing/maker.png'],
- classNames: 'lg-px2 md-px2',
- },
- {
- imageUrl: '/images/landing/loans_icon.png',
- type: 'Decentralized loans',
- description:
- 'Efficient lending requires liquid markets where investors can buy and re-sell loans. \
+ projectIconUrls: ['/images/landing/maker.png'],
+ classNames: 'lg-px2 md-px2',
+ },
+ {
+ imageUrl: '/images/landing/loans_icon.png',
+ type: 'Decentralized loans',
+ description:
+ 'Efficient lending requires liquid markets where investors can buy and re-sell loans. \
0x enables an ecosystem of lenders to self-organize and efficiently determine \
market prices for all outstanding loans.',
- projectIconUrls: ['/images/landing/dharma.png', '/images/landing/lendroid.png'],
- classNames: 'lg-pr2 md-pr2 lg-col-6 md-col-6',
- style: {
- width: 291,
- float: 'right',
- marginTop: !isSmallScreen ? 38 : 0,
- },
- },
- {
- imageUrl: '/images/landing/fund_management_icon.png',
- type: 'Fund management',
- description:
- 'Decentralized fund management limits fund managers to investing in pre-agreed \
+ projectIconUrls: ['/images/landing/dharma.png', '/images/landing/lendroid.png'],
+ classNames: 'lg-pr2 md-pr2 lg-col-6 md-col-6',
+ style: {
+ width: 291,
+ float: 'right',
+ marginTop: !isSmallScreen ? 38 : 0,
+ },
+ },
+ {
+ imageUrl: '/images/landing/fund_management_icon.png',
+ type: 'Fund management',
+ description:
+ 'Decentralized fund management limits fund managers to investing in pre-agreed \
upon asset classes. Embedding 0x into fund management smart contracts enables \
them to enforce these security constraints.',
- projectIconUrls: ['/images/landing/melonport.png'],
- classNames: 'lg-pl2 md-pl2 lg-col-6 md-col-6',
- style: { width: 291, marginTop: !isSmallScreen ? 38 : 0 },
- },
- ];
+ projectIconUrls: ['/images/landing/melonport.png'],
+ classNames: 'lg-pl2 md-pl2 lg-col-6 md-col-6',
+ style: { width: 291, marginTop: !isSmallScreen ? 38 : 0 },
+ },
+ ];
- const cases = _.map(useCases, (useCase: UseCase) => {
- const style = _.isUndefined(useCase.style) || isSmallScreen ? {} : useCase.style;
- const useCaseBoxStyle = {
- color: colors.grey,
- border: '1px solid #565656',
- borderRadius: 4,
- maxWidth: isSmallScreen ? 375 : 'none',
- ...style,
- };
- const typeStyle: React.CSSProperties = {
- color: colors.lightGrey,
- fontSize: 13,
- textTransform: 'uppercase',
- fontFamily: 'Roboto Mono',
- fontWeight: 300,
- };
- return (
- <div
- key={`useCase-${useCase.type}`}
- className={`col lg-col-4 md-col-4 col-12 sm-pt3 sm-px3 sm-pb3 ${useCase.classNames}`}
- >
- <div className="relative p2 pb2 sm-mx-auto" style={useCaseBoxStyle}>
- <div className="absolute center" style={{ top: -35, width: 'calc(100% - 32px)' }}>
- <img src={useCase.imageUrl} style={{ height: 50 }} />
- </div>
- <div className="pt2 center" style={typeStyle}>
- {useCase.type}
- </div>
- <div
- className="pt2"
- style={{
- lineHeight: 1.5,
- fontSize: 14,
- overflow: 'hidden',
- height: 104,
- }}
- >
- {useCase.description}
- </div>
- </div>
- </div>
- );
- });
- return (
- <div className="clearfix pb4 lg-pt2 md-pt2 sm-pt4" style={{ backgroundColor: colors.heroGrey }}>
- <div className="mx-auto pb4 pt3 mt1 sm-mt2 clearfix" style={{ maxWidth: '67em' }}>
- {cases}
- </div>
- </div>
- );
- }
- private _renderCallToAction() {
- const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm;
- const buttonLabelStyle: React.CSSProperties = {
- textTransform: 'none',
- fontSize: 15,
- fontWeight: 400,
- };
- const lightButtonStyle: React.CSSProperties = {
- borderRadius: 6,
- border: '1px solid #a0a0a0',
- lineHeight: '33px',
- height: 49,
- };
- const callToActionClassNames =
- 'col lg-col-8 md-col-8 col-12 lg-pr3 md-pr3 \
+ const cases = _.map(useCases, (useCase: UseCase) => {
+ const style = _.isUndefined(useCase.style) || isSmallScreen ? {} : useCase.style;
+ const useCaseBoxStyle = {
+ color: colors.grey,
+ border: '1px solid #565656',
+ borderRadius: 4,
+ maxWidth: isSmallScreen ? 375 : 'none',
+ ...style,
+ };
+ const typeStyle: React.CSSProperties = {
+ color: colors.lightGrey,
+ fontSize: 13,
+ textTransform: 'uppercase',
+ fontFamily: 'Roboto Mono',
+ fontWeight: 300,
+ };
+ return (
+ <div
+ key={`useCase-${useCase.type}`}
+ className={`col lg-col-4 md-col-4 col-12 sm-pt3 sm-px3 sm-pb3 ${useCase.classNames}`}
+ >
+ <div className="relative p2 pb2 sm-mx-auto" style={useCaseBoxStyle}>
+ <div className="absolute center" style={{ top: -35, width: 'calc(100% - 32px)' }}>
+ <img src={useCase.imageUrl} style={{ height: 50 }} />
+ </div>
+ <div className="pt2 center" style={typeStyle}>
+ {useCase.type}
+ </div>
+ <div
+ className="pt2"
+ style={{
+ lineHeight: 1.5,
+ fontSize: 14,
+ overflow: 'hidden',
+ height: 104,
+ }}
+ >
+ {useCase.description}
+ </div>
+ </div>
+ </div>
+ );
+ });
+ return (
+ <div className="clearfix pb4 lg-pt2 md-pt2 sm-pt4" style={{ backgroundColor: colors.heroGrey }}>
+ <div className="mx-auto pb4 pt3 mt1 sm-mt2 clearfix" style={{ maxWidth: '67em' }}>
+ {cases}
+ </div>
+ </div>
+ );
+ }
+ private _renderCallToAction() {
+ const isSmallScreen = this.state.screenWidth === ScreenWidths.Sm;
+ const buttonLabelStyle: React.CSSProperties = {
+ textTransform: 'none',
+ fontSize: 15,
+ fontWeight: 400,
+ };
+ const lightButtonStyle: React.CSSProperties = {
+ borderRadius: 6,
+ border: '1px solid #a0a0a0',
+ lineHeight: '33px',
+ height: 49,
+ };
+ const callToActionClassNames =
+ 'col lg-col-8 md-col-8 col-12 lg-pr3 md-pr3 \
lg-right-align md-right-align sm-center sm-px3 h4';
- return (
- <div className="clearfix pb4" style={{ backgroundColor: colors.heroGrey }}>
- <div className="mx-auto max-width-4 pb4 mb3 clearfix">
- <div
- className={callToActionClassNames}
- style={{
- fontFamily: 'Roboto Mono',
- color: colors.white,
- lineHeight: isSmallScreen ? 1.7 : 3,
- }}
- >
- Get started on building the decentralized future
- </div>
- <div className="col lg-col-4 md-col-4 col-12 sm-center sm-pt2">
- <Link to={WebsitePaths.ZeroExJs} className="text-decoration-none">
- <RaisedButton
- style={{ borderRadius: 6, minWidth: 150 }}
- buttonStyle={lightButtonStyle}
- labelColor={colors.white}
- backgroundColor={colors.heroGrey}
- labelStyle={buttonLabelStyle}
- label="Build on 0x"
- onClick={_.noop}
- />
- </Link>
- </div>
- </div>
- </div>
- );
- }
- private _updateScreenWidth() {
- const newScreenWidth = utils.getScreenWidth();
- if (newScreenWidth !== this.state.screenWidth) {
- this.setState({
- screenWidth: newScreenWidth,
- });
- }
- }
+ return (
+ <div className="clearfix pb4" style={{ backgroundColor: colors.heroGrey }}>
+ <div className="mx-auto max-width-4 pb4 mb3 clearfix">
+ <div
+ className={callToActionClassNames}
+ style={{
+ fontFamily: 'Roboto Mono',
+ color: colors.white,
+ lineHeight: isSmallScreen ? 1.7 : 3,
+ }}
+ >
+ Get started on building the decentralized future
+ </div>
+ <div className="col lg-col-4 md-col-4 col-12 sm-center sm-pt2">
+ <Link to={WebsitePaths.ZeroExJs} className="text-decoration-none">
+ <RaisedButton
+ style={{ borderRadius: 6, minWidth: 150 }}
+ buttonStyle={lightButtonStyle}
+ labelColor={colors.white}
+ backgroundColor={colors.heroGrey}
+ labelStyle={buttonLabelStyle}
+ label="Build on 0x"
+ onClick={_.noop}
+ />
+ </Link>
+ </div>
+ </div>
+ </div>
+ );
+ }
+ private _updateScreenWidth() {
+ const newScreenWidth = utils.getScreenWidth();
+ if (newScreenWidth !== this.state.screenWidth) {
+ this.setState({
+ screenWidth: newScreenWidth,
+ });
+ }
+ }
} // tslint:disable:max-file-line-count
diff --git a/packages/website/ts/pages/not_found.tsx b/packages/website/ts/pages/not_found.tsx
index 9d8d4142d..ff277c377 100644
--- a/packages/website/ts/pages/not_found.tsx
+++ b/packages/website/ts/pages/not_found.tsx
@@ -5,38 +5,38 @@ import { TopBar } from 'ts/components/top_bar';
import { Styles } from 'ts/types';
export interface NotFoundProps {
- location: Location;
+ location: Location;
}
interface NotFoundState {}
const styles: Styles = {
- thin: {
- fontWeight: 100,
- },
+ thin: {
+ fontWeight: 100,
+ },
};
export class NotFound extends React.Component<NotFoundProps, NotFoundState> {
- public render() {
- return (
- <div>
- <TopBar blockchainIsLoaded={false} location={this.props.location} />
- <div className="mx-auto max-width-4 py4">
- <div className="center py4">
- <div className="py4">
- <div className="py4">
- <h1 style={{ ...styles.thin }}>404 Not Found</h1>
- <div className="py1">
- <div className="py3">
- Hm... looks like we couldn't find what you are looking for.
- </div>
- </div>
- </div>
- </div>
- </div>
- </div>
- <Footer />
- </div>
- );
- }
+ public render() {
+ return (
+ <div>
+ <TopBar blockchainIsLoaded={false} location={this.props.location} />
+ <div className="mx-auto max-width-4 py4">
+ <div className="center py4">
+ <div className="py4">
+ <div className="py4">
+ <h1 style={{ ...styles.thin }}>404 Not Found</h1>
+ <div className="py1">
+ <div className="py3">
+ Hm... looks like we couldn't find what you are looking for.
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ <Footer />
+ </div>
+ );
+ }
}
diff --git a/packages/website/ts/pages/shared/anchor_title.tsx b/packages/website/ts/pages/shared/anchor_title.tsx
index 118aa0ea5..db5be1f59 100644
--- a/packages/website/ts/pages/shared/anchor_title.tsx
+++ b/packages/website/ts/pages/shared/anchor_title.tsx
@@ -5,87 +5,87 @@ import { constants } from 'ts/utils/constants';
import { utils } from 'ts/utils/utils';
const headerSizeToScrollOffset: { [headerSize: string]: number } = {
- h2: -20,
- h3: 0,
+ h2: -20,
+ h3: 0,
};
interface AnchorTitleProps {
- title: string | React.ReactNode;
- id: string;
- headerSize: HeaderSizes;
- shouldShowAnchor: boolean;
+ title: string | React.ReactNode;
+ id: string;
+ headerSize: HeaderSizes;
+ shouldShowAnchor: boolean;
}
interface AnchorTitleState {
- isHovering: boolean;
+ isHovering: boolean;
}
const styles: Styles = {
- anchor: {
- fontSize: 20,
- transform: 'rotate(45deg)',
- cursor: 'pointer',
- },
- headers: {
- WebkitMarginStart: 0,
- WebkitMarginEnd: 0,
- fontWeight: 'bold',
- display: 'block',
- },
- h1: {
- fontSize: '1.8em',
- WebkitMarginBefore: '0.83em',
- WebkitMarginAfter: '0.83em',
- },
- h2: {
- fontSize: '1.5em',
- WebkitMarginBefore: '0.83em',
- WebkitMarginAfter: '0.83em',
- },
- h3: {
- fontSize: '1.17em',
- WebkitMarginBefore: '1em',
- WebkitMarginAfter: '1em',
- },
+ anchor: {
+ fontSize: 20,
+ transform: 'rotate(45deg)',
+ cursor: 'pointer',
+ },
+ headers: {
+ WebkitMarginStart: 0,
+ WebkitMarginEnd: 0,
+ fontWeight: 'bold',
+ display: 'block',
+ },
+ h1: {
+ fontSize: '1.8em',
+ WebkitMarginBefore: '0.83em',
+ WebkitMarginAfter: '0.83em',
+ },
+ h2: {
+ fontSize: '1.5em',
+ WebkitMarginBefore: '0.83em',
+ WebkitMarginAfter: '0.83em',
+ },
+ h3: {
+ fontSize: '1.17em',
+ WebkitMarginBefore: '1em',
+ WebkitMarginAfter: '1em',
+ },
};
export class AnchorTitle extends React.Component<AnchorTitleProps, AnchorTitleState> {
- constructor(props: AnchorTitleProps) {
- super(props);
- this.state = {
- isHovering: false,
- };
- }
- public render() {
- let opacity = 0;
- if (this.props.shouldShowAnchor) {
- opacity = this.state.isHovering ? 0.6 : 1;
- }
- return (
- <div className="relative flex" style={{ ...styles[this.props.headerSize], ...styles.headers }}>
- <div className="inline-block" style={{ paddingRight: 4 }}>
- {this.props.title}
- </div>
- <ScrollLink
- to={this.props.id}
- offset={headerSizeToScrollOffset[this.props.headerSize]}
- duration={constants.DOCS_SCROLL_DURATION_MS}
- containerId={constants.DOCS_CONTAINER_ID}
- >
- <i
- className="zmdi zmdi-link"
- onClick={utils.setUrlHash.bind(utils, this.props.id)}
- style={{ ...styles.anchor, opacity }}
- onMouseOver={this._setHoverState.bind(this, true)}
- onMouseOut={this._setHoverState.bind(this, false)}
- />
- </ScrollLink>
- </div>
- );
- }
- private _setHoverState(isHovering: boolean) {
- this.setState({
- isHovering,
- });
- }
+ constructor(props: AnchorTitleProps) {
+ super(props);
+ this.state = {
+ isHovering: false,
+ };
+ }
+ public render() {
+ let opacity = 0;
+ if (this.props.shouldShowAnchor) {
+ opacity = this.state.isHovering ? 0.6 : 1;
+ }
+ return (
+ <div className="relative flex" style={{ ...styles[this.props.headerSize], ...styles.headers }}>
+ <div className="inline-block" style={{ paddingRight: 4 }}>
+ {this.props.title}
+ </div>
+ <ScrollLink
+ to={this.props.id}
+ offset={headerSizeToScrollOffset[this.props.headerSize]}
+ duration={constants.DOCS_SCROLL_DURATION_MS}
+ containerId={constants.DOCS_CONTAINER_ID}
+ >
+ <i
+ className="zmdi zmdi-link"
+ onClick={utils.setUrlHash.bind(utils, this.props.id)}
+ style={{ ...styles.anchor, opacity }}
+ onMouseOver={this._setHoverState.bind(this, true)}
+ onMouseOut={this._setHoverState.bind(this, false)}
+ />
+ </ScrollLink>
+ </div>
+ );
+ }
+ private _setHoverState(isHovering: boolean) {
+ this.setState({
+ isHovering,
+ });
+ }
}
diff --git a/packages/website/ts/pages/shared/markdown_code_block.tsx b/packages/website/ts/pages/shared/markdown_code_block.tsx
index a9d95979b..be96fda16 100644
--- a/packages/website/ts/pages/shared/markdown_code_block.tsx
+++ b/packages/website/ts/pages/shared/markdown_code_block.tsx
@@ -3,23 +3,23 @@ import * as React from 'react';
import * as HighLight from 'react-highlight';
interface MarkdownCodeBlockProps {
- literal: string;
- language: string;
+ literal: string;
+ language: string;
}
interface MarkdownCodeBlockState {}
export class MarkdownCodeBlock extends React.Component<MarkdownCodeBlockProps, MarkdownCodeBlockState> {
- // Re-rendering a codeblock causes any use selection to become de-selected. This is annoying when trying
- // to copy-paste code examples. We therefore noop re-renders on this component if it's props haven't changed.
- public shouldComponentUpdate(nextProps: MarkdownCodeBlockProps, nextState: MarkdownCodeBlockState) {
- return nextProps.literal !== this.props.literal || nextProps.language !== this.props.language;
- }
- public render() {
- return (
- <span style={{ fontSize: 16 }}>
- <HighLight className={this.props.language || 'javascript'}>{this.props.literal}</HighLight>
- </span>
- );
- }
+ // Re-rendering a codeblock causes any use selection to become de-selected. This is annoying when trying
+ // to copy-paste code examples. We therefore noop re-renders on this component if it's props haven't changed.
+ public shouldComponentUpdate(nextProps: MarkdownCodeBlockProps, nextState: MarkdownCodeBlockState) {
+ return nextProps.literal !== this.props.literal || nextProps.language !== this.props.language;
+ }
+ public render() {
+ return (
+ <span style={{ fontSize: 16 }}>
+ <HighLight className={this.props.language || 'javascript'}>{this.props.literal}</HighLight>
+ </span>
+ );
+ }
}
diff --git a/packages/website/ts/pages/shared/markdown_section.tsx b/packages/website/ts/pages/shared/markdown_section.tsx
index c875ab736..5487dc8cc 100644
--- a/packages/website/ts/pages/shared/markdown_section.tsx
+++ b/packages/website/ts/pages/shared/markdown_section.tsx
@@ -9,66 +9,66 @@ import { HeaderSizes } from 'ts/types';
import { utils } from 'ts/utils/utils';
interface MarkdownSectionProps {
- sectionName: string;
- markdownContent: string;
- headerSize?: HeaderSizes;
- githubLink?: string;
+ sectionName: string;
+ markdownContent: string;
+ headerSize?: HeaderSizes;
+ githubLink?: string;
}
interface MarkdownSectionState {
- shouldShowAnchor: boolean;
+ shouldShowAnchor: boolean;
}
export class MarkdownSection extends React.Component<MarkdownSectionProps, MarkdownSectionState> {
- public static defaultProps: Partial<MarkdownSectionProps> = {
- headerSize: HeaderSizes.H3,
- };
- constructor(props: MarkdownSectionProps) {
- super(props);
- this.state = {
- shouldShowAnchor: false,
- };
- }
- public render() {
- const sectionName = this.props.sectionName;
- const id = utils.getIdFromName(sectionName);
- return (
- <div
- className="pt2 pr3 md-pl2 sm-pl3 overflow-hidden"
- onMouseOver={this._setAnchorVisibility.bind(this, true)}
- onMouseOut={this._setAnchorVisibility.bind(this, false)}
- >
- <ScrollElement name={id}>
- <div className="clearfix">
- <div className="col lg-col-8 md-col-8 sm-col-12">
- <span style={{ textTransform: 'capitalize' }}>
- <AnchorTitle
- headerSize={this.props.headerSize}
- title={sectionName}
- id={id}
- shouldShowAnchor={this.state.shouldShowAnchor}
- />
- </span>
- </div>
- <div className="col col-4 sm-hide xs-hide py2 right-align">
- {!_.isUndefined(this.props.githubLink) && (
- <RaisedButton
- href={this.props.githubLink}
- target="_blank"
- label="Edit on Github"
- icon={<i className="zmdi zmdi-github" style={{ fontSize: 23 }} />}
- />
- )}
- </div>
- </div>
- <ReactMarkdown source={this.props.markdownContent} renderers={{ CodeBlock: MarkdownCodeBlock }} />
- </ScrollElement>
- </div>
- );
- }
- private _setAnchorVisibility(shouldShowAnchor: boolean) {
- this.setState({
- shouldShowAnchor,
- });
- }
+ public static defaultProps: Partial<MarkdownSectionProps> = {
+ headerSize: HeaderSizes.H3,
+ };
+ constructor(props: MarkdownSectionProps) {
+ super(props);
+ this.state = {
+ shouldShowAnchor: false,
+ };
+ }
+ public render() {
+ const sectionName = this.props.sectionName;
+ const id = utils.getIdFromName(sectionName);
+ return (
+ <div
+ className="pt2 pr3 md-pl2 sm-pl3 overflow-hidden"
+ onMouseOver={this._setAnchorVisibility.bind(this, true)}
+ onMouseOut={this._setAnchorVisibility.bind(this, false)}
+ >
+ <ScrollElement name={id}>
+ <div className="clearfix">
+ <div className="col lg-col-8 md-col-8 sm-col-12">
+ <span style={{ textTransform: 'capitalize' }}>
+ <AnchorTitle
+ headerSize={this.props.headerSize}
+ title={sectionName}
+ id={id}
+ shouldShowAnchor={this.state.shouldShowAnchor}
+ />
+ </span>
+ </div>
+ <div className="col col-4 sm-hide xs-hide py2 right-align">
+ {!_.isUndefined(this.props.githubLink) && (
+ <RaisedButton
+ href={this.props.githubLink}
+ target="_blank"
+ label="Edit on Github"
+ icon={<i className="zmdi zmdi-github" style={{ fontSize: 23 }} />}
+ />
+ )}
+ </div>
+ </div>
+ <ReactMarkdown source={this.props.markdownContent} renderers={{ CodeBlock: MarkdownCodeBlock }} />
+ </ScrollElement>
+ </div>
+ );
+ }
+ private _setAnchorVisibility(shouldShowAnchor: boolean) {
+ this.setState({
+ shouldShowAnchor,
+ });
+ }
}
diff --git a/packages/website/ts/pages/shared/nested_sidebar_menu.tsx b/packages/website/ts/pages/shared/nested_sidebar_menu.tsx
index cd7ea68e6..849c33504 100644
--- a/packages/website/ts/pages/shared/nested_sidebar_menu.tsx
+++ b/packages/website/ts/pages/shared/nested_sidebar_menu.tsx
@@ -9,146 +9,146 @@ import { constants } from 'ts/utils/constants';
import { utils } from 'ts/utils/utils';
interface NestedSidebarMenuProps {
- topLevelMenu: { [topLevel: string]: string[] };
- menuSubsectionsBySection: MenuSubsectionsBySection;
- shouldDisplaySectionHeaders?: boolean;
- onMenuItemClick?: () => void;
- selectedVersion?: string;
- versions?: string[];
- docPath?: string;
- isSectionHeaderClickable?: boolean;
+ topLevelMenu: { [topLevel: string]: string[] };
+ menuSubsectionsBySection: MenuSubsectionsBySection;
+ shouldDisplaySectionHeaders?: boolean;
+ onMenuItemClick?: () => void;
+ selectedVersion?: string;
+ versions?: string[];
+ docPath?: string;
+ isSectionHeaderClickable?: boolean;
}
interface NestedSidebarMenuState {}
const styles: Styles = {
- menuItemWithHeaders: {
- minHeight: 0,
- },
- menuItemWithoutHeaders: {
- minHeight: 48,
- },
- menuItemInnerDivWithHeaders: {
- lineHeight: 2,
- },
+ menuItemWithHeaders: {
+ minHeight: 0,
+ },
+ menuItemWithoutHeaders: {
+ minHeight: 48,
+ },
+ menuItemInnerDivWithHeaders: {
+ lineHeight: 2,
+ },
};
export class NestedSidebarMenu extends React.Component<NestedSidebarMenuProps, NestedSidebarMenuState> {
- public static defaultProps: Partial<NestedSidebarMenuProps> = {
- shouldDisplaySectionHeaders: true,
- onMenuItemClick: _.noop,
- };
- public render() {
- const navigation = _.map(this.props.topLevelMenu, (menuItems: string[], sectionName: string) => {
- const finalSectionName = sectionName.replace(/-/g, ' ');
- if (this.props.shouldDisplaySectionHeaders) {
- const id = utils.getIdFromName(sectionName);
- return (
- <div key={`section-${sectionName}`} className="py1">
- <ScrollLink
- to={id}
- offset={-20}
- duration={constants.DOCS_SCROLL_DURATION_MS}
- containerId={constants.DOCS_CONTAINER_ID}
- >
- <div style={{ color: colors.grey, cursor: 'pointer' }} className="pb1">
- {finalSectionName.toUpperCase()}
- </div>
- </ScrollLink>
- {this._renderMenuItems(menuItems)}
- </div>
- );
- } else {
- return <div key={`section-${sectionName}`}>{this._renderMenuItems(menuItems)}</div>;
- }
- });
- return (
- <div>
- {!_.isUndefined(this.props.versions) &&
- !_.isUndefined(this.props.selectedVersion) &&
- !_.isUndefined(this.props.docPath) && (
- <VersionDropDown
- selectedVersion={this.props.selectedVersion}
- versions={this.props.versions}
- docPath={this.props.docPath}
- />
- )}
- {navigation}
- </div>
- );
- }
- private _renderMenuItems(menuItemNames: string[]): React.ReactNode[] {
- const menuItemStyles = this.props.shouldDisplaySectionHeaders
- ? styles.menuItemWithHeaders
- : styles.menuItemWithoutHeaders;
- const menuItemInnerDivStyles = this.props.shouldDisplaySectionHeaders ? styles.menuItemInnerDivWithHeaders : {};
- const menuItems = _.map(menuItemNames, menuItemName => {
- const id = utils.getIdFromName(menuItemName);
- return (
- <div key={menuItemName}>
- <ScrollLink
- key={`menuItem-${menuItemName}`}
- to={id}
- offset={-10}
- duration={constants.DOCS_SCROLL_DURATION_MS}
- containerId={constants.DOCS_CONTAINER_ID}
- >
- <MenuItem
- onTouchTap={this._onMenuItemClick.bind(this, menuItemName)}
- style={menuItemStyles}
- innerDivStyle={menuItemInnerDivStyles}
- >
- <span style={{ textTransform: 'capitalize' }}>{menuItemName}</span>
- </MenuItem>
- </ScrollLink>
- {this._renderMenuItemSubsections(menuItemName)}
- </div>
- );
- });
- return menuItems;
- }
- private _renderMenuItemSubsections(menuItemName: string): React.ReactNode {
- if (_.isUndefined(this.props.menuSubsectionsBySection[menuItemName])) {
- return null;
- }
- return this._renderMenuSubsectionsBySection(menuItemName, this.props.menuSubsectionsBySection[menuItemName]);
- }
- private _renderMenuSubsectionsBySection(menuItemName: string, entityNames: string[]): React.ReactNode {
- return (
- <ul style={{ margin: 0, listStyleType: 'none', paddingLeft: 0 }} key={menuItemName}>
- {_.map(entityNames, entityName => {
- const name = `${menuItemName}-${entityName}`;
- const id = utils.getIdFromName(name);
- return (
- <li key={`menuItem-${entityName}`}>
- <ScrollLink
- to={id}
- offset={0}
- duration={constants.DOCS_SCROLL_DURATION_MS}
- containerId={constants.DOCS_CONTAINER_ID}
- onTouchTap={this._onMenuItemClick.bind(this, name)}
- >
- <MenuItem
- onTouchTap={this._onMenuItemClick.bind(this, name)}
- style={{ minHeight: 35 }}
- innerDivStyle={{
- paddingLeft: 36,
- fontSize: 14,
- lineHeight: '35px',
- }}
- >
- {entityName}
- </MenuItem>
- </ScrollLink>
- </li>
- );
- })}
- </ul>
- );
- }
- private _onMenuItemClick(name: string): void {
- const id = utils.getIdFromName(name);
- utils.setUrlHash(id);
- this.props.onMenuItemClick();
- }
+ public static defaultProps: Partial<NestedSidebarMenuProps> = {
+ shouldDisplaySectionHeaders: true,
+ onMenuItemClick: _.noop,
+ };
+ public render() {
+ const navigation = _.map(this.props.topLevelMenu, (menuItems: string[], sectionName: string) => {
+ const finalSectionName = sectionName.replace(/-/g, ' ');
+ if (this.props.shouldDisplaySectionHeaders) {
+ const id = utils.getIdFromName(sectionName);
+ return (
+ <div key={`section-${sectionName}`} className="py1">
+ <ScrollLink
+ to={id}
+ offset={-20}
+ duration={constants.DOCS_SCROLL_DURATION_MS}
+ containerId={constants.DOCS_CONTAINER_ID}
+ >
+ <div style={{ color: colors.grey, cursor: 'pointer' }} className="pb1">
+ {finalSectionName.toUpperCase()}
+ </div>
+ </ScrollLink>
+ {this._renderMenuItems(menuItems)}
+ </div>
+ );
+ } else {
+ return <div key={`section-${sectionName}`}>{this._renderMenuItems(menuItems)}</div>;
+ }
+ });
+ return (
+ <div>
+ {!_.isUndefined(this.props.versions) &&
+ !_.isUndefined(this.props.selectedVersion) &&
+ !_.isUndefined(this.props.docPath) && (
+ <VersionDropDown
+ selectedVersion={this.props.selectedVersion}
+ versions={this.props.versions}
+ docPath={this.props.docPath}
+ />
+ )}
+ {navigation}
+ </div>
+ );
+ }
+ private _renderMenuItems(menuItemNames: string[]): React.ReactNode[] {
+ const menuItemStyles = this.props.shouldDisplaySectionHeaders
+ ? styles.menuItemWithHeaders
+ : styles.menuItemWithoutHeaders;
+ const menuItemInnerDivStyles = this.props.shouldDisplaySectionHeaders ? styles.menuItemInnerDivWithHeaders : {};
+ const menuItems = _.map(menuItemNames, menuItemName => {
+ const id = utils.getIdFromName(menuItemName);
+ return (
+ <div key={menuItemName}>
+ <ScrollLink
+ key={`menuItem-${menuItemName}`}
+ to={id}
+ offset={-10}
+ duration={constants.DOCS_SCROLL_DURATION_MS}
+ containerId={constants.DOCS_CONTAINER_ID}
+ >
+ <MenuItem
+ onTouchTap={this._onMenuItemClick.bind(this, menuItemName)}
+ style={menuItemStyles}
+ innerDivStyle={menuItemInnerDivStyles}
+ >
+ <span style={{ textTransform: 'capitalize' }}>{menuItemName}</span>
+ </MenuItem>
+ </ScrollLink>
+ {this._renderMenuItemSubsections(menuItemName)}
+ </div>
+ );
+ });
+ return menuItems;
+ }
+ private _renderMenuItemSubsections(menuItemName: string): React.ReactNode {
+ if (_.isUndefined(this.props.menuSubsectionsBySection[menuItemName])) {
+ return null;
+ }
+ return this._renderMenuSubsectionsBySection(menuItemName, this.props.menuSubsectionsBySection[menuItemName]);
+ }
+ private _renderMenuSubsectionsBySection(menuItemName: string, entityNames: string[]): React.ReactNode {
+ return (
+ <ul style={{ margin: 0, listStyleType: 'none', paddingLeft: 0 }} key={menuItemName}>
+ {_.map(entityNames, entityName => {
+ const name = `${menuItemName}-${entityName}`;
+ const id = utils.getIdFromName(name);
+ return (
+ <li key={`menuItem-${entityName}`}>
+ <ScrollLink
+ to={id}
+ offset={0}
+ duration={constants.DOCS_SCROLL_DURATION_MS}
+ containerId={constants.DOCS_CONTAINER_ID}
+ onTouchTap={this._onMenuItemClick.bind(this, name)}
+ >
+ <MenuItem
+ onTouchTap={this._onMenuItemClick.bind(this, name)}
+ style={{ minHeight: 35 }}
+ innerDivStyle={{
+ paddingLeft: 36,
+ fontSize: 14,
+ lineHeight: '35px',
+ }}
+ >
+ {entityName}
+ </MenuItem>
+ </ScrollLink>
+ </li>
+ );
+ })}
+ </ul>
+ );
+ }
+ private _onMenuItemClick(name: string): void {
+ const id = utils.getIdFromName(name);
+ utils.setUrlHash(id);
+ this.props.onMenuItemClick();
+ }
}
diff --git a/packages/website/ts/pages/shared/section_header.tsx b/packages/website/ts/pages/shared/section_header.tsx
index f9aa1a5e6..a5f5f52cf 100644
--- a/packages/website/ts/pages/shared/section_header.tsx
+++ b/packages/website/ts/pages/shared/section_header.tsx
@@ -5,46 +5,46 @@ import { HeaderSizes } from 'ts/types';
import { utils } from 'ts/utils/utils';
interface SectionHeaderProps {
- sectionName: string;
- headerSize?: HeaderSizes;
+ sectionName: string;
+ headerSize?: HeaderSizes;
}
interface SectionHeaderState {
- shouldShowAnchor: boolean;
+ shouldShowAnchor: boolean;
}
export class SectionHeader extends React.Component<SectionHeaderProps, SectionHeaderState> {
- public static defaultProps: Partial<SectionHeaderProps> = {
- headerSize: HeaderSizes.H2,
- };
- constructor(props: SectionHeaderProps) {
- super(props);
- this.state = {
- shouldShowAnchor: false,
- };
- }
- public render() {
- const sectionName = this.props.sectionName.replace(/-/g, ' ');
- const id = utils.getIdFromName(sectionName);
- return (
- <div
- onMouseOver={this._setAnchorVisibility.bind(this, true)}
- onMouseOut={this._setAnchorVisibility.bind(this, false)}
- >
- <ScrollElement name={id}>
- <AnchorTitle
- headerSize={this.props.headerSize}
- title={<span style={{ textTransform: 'capitalize' }}>{sectionName}</span>}
- id={id}
- shouldShowAnchor={this.state.shouldShowAnchor}
- />
- </ScrollElement>
- </div>
- );
- }
- private _setAnchorVisibility(shouldShowAnchor: boolean) {
- this.setState({
- shouldShowAnchor,
- });
- }
+ public static defaultProps: Partial<SectionHeaderProps> = {
+ headerSize: HeaderSizes.H2,
+ };
+ constructor(props: SectionHeaderProps) {
+ super(props);
+ this.state = {
+ shouldShowAnchor: false,
+ };
+ }
+ public render() {
+ const sectionName = this.props.sectionName.replace(/-/g, ' ');
+ const id = utils.getIdFromName(sectionName);
+ return (
+ <div
+ onMouseOver={this._setAnchorVisibility.bind(this, true)}
+ onMouseOut={this._setAnchorVisibility.bind(this, false)}
+ >
+ <ScrollElement name={id}>
+ <AnchorTitle
+ headerSize={this.props.headerSize}
+ title={<span style={{ textTransform: 'capitalize' }}>{sectionName}</span>}
+ id={id}
+ shouldShowAnchor={this.state.shouldShowAnchor}
+ />
+ </ScrollElement>
+ </div>
+ );
+ }
+ private _setAnchorVisibility(shouldShowAnchor: boolean) {
+ this.setState({
+ shouldShowAnchor,
+ });
+ }
}
diff --git a/packages/website/ts/pages/shared/version_drop_down.tsx b/packages/website/ts/pages/shared/version_drop_down.tsx
index a647252ba..b922e1048 100644
--- a/packages/website/ts/pages/shared/version_drop_down.tsx
+++ b/packages/website/ts/pages/shared/version_drop_down.tsx
@@ -4,34 +4,34 @@ import MenuItem from 'material-ui/MenuItem';
import * as React from 'react';
interface VersionDropDownProps {
- selectedVersion: string;
- versions: string[];
- docPath: string;
+ selectedVersion: string;
+ versions: string[];
+ docPath: string;
}
interface VersionDropDownState {}
export class VersionDropDown extends React.Component<VersionDropDownProps, VersionDropDownState> {
- public render() {
- return (
- <div className="mx-auto" style={{ width: 120 }}>
- <DropDownMenu
- maxHeight={300}
- value={this.props.selectedVersion}
- onChange={this._updateSelectedVersion.bind(this)}
- >
- {this._renderDropDownItems()}
- </DropDownMenu>
- </div>
- );
- }
- private _renderDropDownItems() {
- const items = _.map(this.props.versions, version => {
- return <MenuItem key={version} value={version} primaryText={`v${version}`} />;
- });
- return items;
- }
- private _updateSelectedVersion(e: any, index: number, value: string) {
- window.location.href = `${this.props.docPath}/${value}${window.location.hash}`;
- }
+ public render() {
+ return (
+ <div className="mx-auto" style={{ width: 120 }}>
+ <DropDownMenu
+ maxHeight={300}
+ value={this.props.selectedVersion}
+ onChange={this._updateSelectedVersion.bind(this)}
+ >
+ {this._renderDropDownItems()}
+ </DropDownMenu>
+ </div>
+ );
+ }
+ private _renderDropDownItems() {
+ const items = _.map(this.props.versions, version => {
+ return <MenuItem key={version} value={version} primaryText={`v${version}`} />;
+ });
+ return items;
+ }
+ private _updateSelectedVersion(e: any, index: number, value: string) {
+ window.location.href = `${this.props.docPath}/${value}${window.location.hash}`;
+ }
}
diff --git a/packages/website/ts/pages/wiki/wiki.tsx b/packages/website/ts/pages/wiki/wiki.tsx
index dba5ed6a0..d065614ba 100644
--- a/packages/website/ts/pages/wiki/wiki.tsx
+++ b/packages/website/ts/pages/wiki/wiki.tsx
@@ -16,186 +16,186 @@ import { utils } from 'ts/utils/utils';
const WIKI_NOT_READY_BACKOUT_TIMEOUT_MS = 5000;
export interface WikiProps {
- source: string;
- location: Location;
+ source: string;
+ location: Location;
}
interface WikiState {
- articlesBySection: ArticlesBySection;
+ articlesBySection: ArticlesBySection;
}
const styles: Styles = {
- mainContainers: {
- position: 'absolute',
- top: 1,
- left: 0,
- bottom: 0,
- right: 0,
- overflowZ: 'hidden',
- overflowY: 'scroll',
- minHeight: 'calc(100vh - 1px)',
- WebkitOverflowScrolling: 'touch',
- },
- menuContainer: {
- borderColor: colors.grey300,
- maxWidth: 330,
- marginLeft: 20,
- },
+ mainContainers: {
+ position: 'absolute',
+ top: 1,
+ left: 0,
+ bottom: 0,
+ right: 0,
+ overflowZ: 'hidden',
+ overflowY: 'scroll',
+ minHeight: 'calc(100vh - 1px)',
+ WebkitOverflowScrolling: 'touch',
+ },
+ menuContainer: {
+ borderColor: colors.grey300,
+ maxWidth: 330,
+ marginLeft: 20,
+ },
};
export class Wiki extends React.Component<WikiProps, WikiState> {
- private _wikiBackoffTimeoutId: number;
- constructor(props: WikiProps) {
- super(props);
- this.state = {
- articlesBySection: undefined,
- };
- }
- public componentWillMount() {
- // tslint:disable-next-line:no-floating-promises
- this._fetchArticlesBySectionAsync();
- }
- public componentWillUnmount() {
- clearTimeout(this._wikiBackoffTimeoutId);
- }
- public render() {
- const menuSubsectionsBySection = _.isUndefined(this.state.articlesBySection)
- ? {}
- : this._getMenuSubsectionsBySection(this.state.articlesBySection);
- return (
- <div>
- <DocumentTitle title="0x Protocol Wiki" />
- <TopBar
- blockchainIsLoaded={false}
- location={this.props.location}
- menuSubsectionsBySection={menuSubsectionsBySection}
- shouldFullWidth={true}
- />
- {_.isUndefined(this.state.articlesBySection) ? (
- <div className="col col-12" style={styles.mainContainers}>
- <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 wiki...
- </div>
- </div>
- </div>
- ) : (
- <div className="mx-auto flex" style={{ color: colors.grey800, height: 43 }}>
- <div className="relative col md-col-3 lg-col-3 lg-pl0 md-pl1 sm-hide xs-hide">
- <div
- className="border-right absolute pt2"
- style={{ ...styles.menuContainer, ...styles.mainContainers }}
- >
- <NestedSidebarMenu
- topLevelMenu={menuSubsectionsBySection}
- menuSubsectionsBySection={menuSubsectionsBySection}
- isSectionHeaderClickable={true}
- />
- </div>
- </div>
- <div className="relative col lg-col-9 md-col-9 sm-col-12 col-12">
- <div id="documentation" style={styles.mainContainers} className="absolute">
- <div id="0xProtocolWiki" />
- <h1 className="md-pl2 sm-pl3">
- <a href={constants.URL_GITHUB_WIKI} target="_blank">
- 0x Protocol Wiki
- </a>
- </h1>
- <div id="wiki">{this._renderWikiArticles()}</div>
- </div>
- </div>
- </div>
- )}
- </div>
- );
- }
- private _renderWikiArticles(): React.ReactNode {
- const sectionNames = _.keys(this.state.articlesBySection);
- const sections = _.map(sectionNames, sectionName => this._renderSection(sectionName));
- return sections;
- }
- private _renderSection(sectionName: string) {
- const articles = this.state.articlesBySection[sectionName];
- const renderedArticles = _.map(articles, (article: Article) => {
- const githubLink = `${constants.URL_GITHUB_WIKI}/edit/master/${sectionName}/${article.fileName}`;
- return (
- <div key={`markdown-section-${article.title}`}>
- <MarkdownSection
- sectionName={article.title}
- markdownContent={article.content}
- headerSize={HeaderSizes.H2}
- githubLink={githubLink}
- />
- <div className="mb4 mt3 p3 center" style={{ backgroundColor: colors.lightestGrey }}>
- See a way to make this article better?{' '}
- <a href={githubLink} target="_blank">
- Edit here →
- </a>
- </div>
- </div>
- );
- });
- return (
- <div key={`section-${sectionName}`} className="py2 pr3 md-pl2 sm-pl3">
- <SectionHeader sectionName={sectionName} headerSize={HeaderSizes.H1} />
- {renderedArticles}
- </div>
- );
- }
- private _scrollToHash(): void {
- const hashWithPrefix = this.props.location.hash;
- let hash = hashWithPrefix.slice(1);
- if (_.isEmpty(hash)) {
- hash = '0xProtocolWiki'; // scroll to the top
- }
+ private _wikiBackoffTimeoutId: number;
+ constructor(props: WikiProps) {
+ super(props);
+ this.state = {
+ articlesBySection: undefined,
+ };
+ }
+ public componentWillMount() {
+ // tslint:disable-next-line:no-floating-promises
+ this._fetchArticlesBySectionAsync();
+ }
+ public componentWillUnmount() {
+ clearTimeout(this._wikiBackoffTimeoutId);
+ }
+ public render() {
+ const menuSubsectionsBySection = _.isUndefined(this.state.articlesBySection)
+ ? {}
+ : this._getMenuSubsectionsBySection(this.state.articlesBySection);
+ return (
+ <div>
+ <DocumentTitle title="0x Protocol Wiki" />
+ <TopBar
+ blockchainIsLoaded={false}
+ location={this.props.location}
+ menuSubsectionsBySection={menuSubsectionsBySection}
+ shouldFullWidth={true}
+ />
+ {_.isUndefined(this.state.articlesBySection) ? (
+ <div className="col col-12" style={styles.mainContainers}>
+ <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 wiki...
+ </div>
+ </div>
+ </div>
+ ) : (
+ <div className="mx-auto flex" style={{ color: colors.grey800, height: 43 }}>
+ <div className="relative col md-col-3 lg-col-3 lg-pl0 md-pl1 sm-hide xs-hide">
+ <div
+ className="border-right absolute pt2"
+ style={{ ...styles.menuContainer, ...styles.mainContainers }}
+ >
+ <NestedSidebarMenu
+ topLevelMenu={menuSubsectionsBySection}
+ menuSubsectionsBySection={menuSubsectionsBySection}
+ isSectionHeaderClickable={true}
+ />
+ </div>
+ </div>
+ <div className="relative col lg-col-9 md-col-9 sm-col-12 col-12">
+ <div id="documentation" style={styles.mainContainers} className="absolute">
+ <div id="0xProtocolWiki" />
+ <h1 className="md-pl2 sm-pl3">
+ <a href={constants.URL_GITHUB_WIKI} target="_blank">
+ 0x Protocol Wiki
+ </a>
+ </h1>
+ <div id="wiki">{this._renderWikiArticles()}</div>
+ </div>
+ </div>
+ </div>
+ )}
+ </div>
+ );
+ }
+ private _renderWikiArticles(): React.ReactNode {
+ const sectionNames = _.keys(this.state.articlesBySection);
+ const sections = _.map(sectionNames, sectionName => this._renderSection(sectionName));
+ return sections;
+ }
+ private _renderSection(sectionName: string) {
+ const articles = this.state.articlesBySection[sectionName];
+ const renderedArticles = _.map(articles, (article: Article) => {
+ const githubLink = `${constants.URL_GITHUB_WIKI}/edit/master/${sectionName}/${article.fileName}`;
+ return (
+ <div key={`markdown-section-${article.title}`}>
+ <MarkdownSection
+ sectionName={article.title}
+ markdownContent={article.content}
+ headerSize={HeaderSizes.H2}
+ githubLink={githubLink}
+ />
+ <div className="mb4 mt3 p3 center" style={{ backgroundColor: colors.lightestGrey }}>
+ See a way to make this article better?{' '}
+ <a href={githubLink} target="_blank">
+ Edit here →
+ </a>
+ </div>
+ </div>
+ );
+ });
+ return (
+ <div key={`section-${sectionName}`} className="py2 pr3 md-pl2 sm-pl3">
+ <SectionHeader sectionName={sectionName} headerSize={HeaderSizes.H1} />
+ {renderedArticles}
+ </div>
+ );
+ }
+ private _scrollToHash(): void {
+ const hashWithPrefix = this.props.location.hash;
+ let hash = hashWithPrefix.slice(1);
+ if (_.isEmpty(hash)) {
+ hash = '0xProtocolWiki'; // scroll to the top
+ }
- scroller.scrollTo(hash, {
- duration: 0,
- offset: 0,
- containerId: 'documentation',
- });
- }
- private async _fetchArticlesBySectionAsync(): Promise<void> {
- const endpoint = `${configs.BACKEND_BASE_URL}${WebsitePaths.Wiki}`;
- const response = await fetch(endpoint);
- if (response.status === constants.HTTP_NO_CONTENT_STATUS_CODE) {
- // We need to backoff and try fetching again later
- this._wikiBackoffTimeoutId = window.setTimeout(() => {
- // tslint:disable-next-line:no-floating-promises
- this._fetchArticlesBySectionAsync();
- }, WIKI_NOT_READY_BACKOUT_TIMEOUT_MS);
- return;
- }
- if (response.status !== 200) {
- // TODO: Show the user an error message when the wiki fail to load
- const errMsg = await response.text();
- utils.consoleLog(`Failed to load wiki: ${response.status} ${errMsg}`);
- return;
- }
- const articlesBySection = await response.json();
- this.setState(
- {
- articlesBySection,
- },
- () => {
- this._scrollToHash();
- },
- );
- }
- private _getMenuSubsectionsBySection(articlesBySection: ArticlesBySection) {
- const sectionNames = _.keys(articlesBySection);
- const menuSubsectionsBySection: { [section: string]: string[] } = {};
- for (const sectionName of sectionNames) {
- const articles = articlesBySection[sectionName];
- const articleNames = _.map(articles, article => article.title);
- menuSubsectionsBySection[sectionName] = articleNames;
- }
- return menuSubsectionsBySection;
- }
+ scroller.scrollTo(hash, {
+ duration: 0,
+ offset: 0,
+ containerId: 'documentation',
+ });
+ }
+ private async _fetchArticlesBySectionAsync(): Promise<void> {
+ const endpoint = `${configs.BACKEND_BASE_URL}${WebsitePaths.Wiki}`;
+ const response = await fetch(endpoint);
+ if (response.status === constants.HTTP_NO_CONTENT_STATUS_CODE) {
+ // We need to backoff and try fetching again later
+ this._wikiBackoffTimeoutId = window.setTimeout(() => {
+ // tslint:disable-next-line:no-floating-promises
+ this._fetchArticlesBySectionAsync();
+ }, WIKI_NOT_READY_BACKOUT_TIMEOUT_MS);
+ return;
+ }
+ if (response.status !== 200) {
+ // TODO: Show the user an error message when the wiki fail to load
+ const errMsg = await response.text();
+ utils.consoleLog(`Failed to load wiki: ${response.status} ${errMsg}`);
+ return;
+ }
+ const articlesBySection = await response.json();
+ this.setState(
+ {
+ articlesBySection,
+ },
+ () => {
+ this._scrollToHash();
+ },
+ );
+ }
+ private _getMenuSubsectionsBySection(articlesBySection: ArticlesBySection) {
+ const sectionNames = _.keys(articlesBySection);
+ const menuSubsectionsBySection: { [section: string]: string[] } = {};
+ for (const sectionName of sectionNames) {
+ const articles = articlesBySection[sectionName];
+ const articleNames = _.map(articles, article => article.title);
+ menuSubsectionsBySection[sectionName] = articleNames;
+ }
+ return menuSubsectionsBySection;
+ }
}