Merge pull request #1027 from 0xProject/dev-dropdown
New Topbar Developers Dropdown
This commit is contained in:
@@ -69,20 +69,14 @@ contract MixinExchangeWrapper is
|
||||
fillOrderCalldata, // write output over input
|
||||
128 // output size is 128 bytes
|
||||
)
|
||||
switch success
|
||||
case 0 {
|
||||
mstore(fillResults, 0)
|
||||
mstore(add(fillResults, 32), 0)
|
||||
mstore(add(fillResults, 64), 0)
|
||||
mstore(add(fillResults, 96), 0)
|
||||
}
|
||||
case 1 {
|
||||
if success {
|
||||
mstore(fillResults, mload(fillOrderCalldata))
|
||||
mstore(add(fillResults, 32), mload(add(fillOrderCalldata, 32)))
|
||||
mstore(add(fillResults, 64), mload(add(fillOrderCalldata, 64)))
|
||||
mstore(add(fillResults, 96), mload(add(fillOrderCalldata, 96)))
|
||||
}
|
||||
}
|
||||
// fillResults values will be 0 by default if call was unsuccessful
|
||||
return fillResults;
|
||||
}
|
||||
|
||||
|
||||
@@ -96,6 +96,7 @@ contract MixinWrapperFunctions is
|
||||
mstore(add(fillResults, 96), mload(add(fillOrderCalldata, 96)))
|
||||
}
|
||||
}
|
||||
// fillResults values will be 0 by default if call was unsuccessful
|
||||
return fillResults;
|
||||
}
|
||||
|
||||
|
||||
@@ -67,9 +67,7 @@ describe('Exchange core internal functions', () => {
|
||||
overflowErrorForSendTransaction = new Error(
|
||||
await getRevertReasonOrErrorMessageForSendTransactionAsync(RevertReason.Uint256Overflow),
|
||||
);
|
||||
divisionByZeroErrorForCall = new Error(
|
||||
await getRevertReasonOrErrorMessageForSendTransactionAsync(RevertReason.DivisionByZero),
|
||||
);
|
||||
divisionByZeroErrorForCall = new Error(RevertReason.DivisionByZero);
|
||||
invalidOpcodeErrorForCall = new Error(await getInvalidOpcodeErrorMessageForCallAsync());
|
||||
});
|
||||
// Note(albrow): Don't forget to add beforeEach and afterEach calls to reset
|
||||
|
||||
@@ -6,6 +6,34 @@ import { chaiSetup } from './chai_setup';
|
||||
chaiSetup.configure();
|
||||
const expect = chai.expect;
|
||||
|
||||
class Value<T> {
|
||||
public value: T;
|
||||
constructor(value: T) {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
|
||||
// tslint:disable-next-line: max-classes-per-file
|
||||
class ErrorMessage {
|
||||
public error: string;
|
||||
constructor(message: string) {
|
||||
this.error = message;
|
||||
}
|
||||
}
|
||||
|
||||
type PromiseResult<T> = Value<T> | ErrorMessage;
|
||||
|
||||
// TODO(albrow): This seems like a generic utility function that could exist in
|
||||
// lodash. We should replace it by a library implementation, or move it to our
|
||||
// own.
|
||||
async function evaluatePromise<T>(promise: Promise<T>): Promise<PromiseResult<T>> {
|
||||
try {
|
||||
return new Value<T>(await promise);
|
||||
} catch (e) {
|
||||
return new ErrorMessage(e.message);
|
||||
}
|
||||
}
|
||||
|
||||
export async function testWithReferenceFuncAsync<P0, R>(
|
||||
referenceFunc: (p0: P0) => Promise<R>,
|
||||
testFunc: (p0: P0) => Promise<R>,
|
||||
@@ -64,39 +92,31 @@ export async function testWithReferenceFuncAsync(
|
||||
testFuncAsync: (...args: any[]) => Promise<any>,
|
||||
values: any[],
|
||||
): Promise<void> {
|
||||
let expectedResult: any;
|
||||
let expectedErr: string | undefined;
|
||||
try {
|
||||
expectedResult = await referenceFuncAsync(...values);
|
||||
} catch (e) {
|
||||
expectedErr = e.message;
|
||||
}
|
||||
let actualResult: any | undefined;
|
||||
try {
|
||||
actualResult = await testFuncAsync(...values);
|
||||
if (!_.isUndefined(expectedErr)) {
|
||||
// Measure correct behaviour
|
||||
const expected = await evaluatePromise(referenceFuncAsync(...values));
|
||||
|
||||
// Measure actual behaviour
|
||||
const actual = await evaluatePromise(testFuncAsync(...values));
|
||||
|
||||
// Compare behaviour
|
||||
if (expected instanceof ErrorMessage) {
|
||||
// If we expected an error, check if the actual error message contains the
|
||||
// expected error message.
|
||||
if (!(actual instanceof ErrorMessage)) {
|
||||
throw new Error(
|
||||
`Expected error containing ${expectedErr} but got no error\n\tTest case: ${_getTestCaseString(
|
||||
`Expected error containing ${expected.error} but got no error\n\tTest case: ${_getTestCaseString(
|
||||
referenceFuncAsync,
|
||||
values,
|
||||
)}`,
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
if (_.isUndefined(expectedErr)) {
|
||||
throw new Error(`${e.message}\n\tTest case: ${_getTestCaseString(referenceFuncAsync, values)}`);
|
||||
} else {
|
||||
expect(e.message).to.contain(
|
||||
expectedErr,
|
||||
`${e.message}\n\tTest case: ${_getTestCaseString(referenceFuncAsync, values)}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
if (!_.isUndefined(actualResult) && !_.isUndefined(expectedResult)) {
|
||||
expect(actualResult).to.deep.equal(
|
||||
expectedResult,
|
||||
`Test case: ${_getTestCaseString(referenceFuncAsync, values)}`,
|
||||
expect(actual.error).to.contain(
|
||||
expected.error,
|
||||
`${actual.error}\n\tTest case: ${_getTestCaseString(referenceFuncAsync, values)}`,
|
||||
);
|
||||
} else {
|
||||
// If we do not expect an error, compare actual and expected directly.
|
||||
expect(actual).to.deep.equal(expected, `Test case ${_getTestCaseString(referenceFuncAsync, values)}`);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
63
packages/contracts/test/utils_test/test_with_reference.ts
Normal file
63
packages/contracts/test/utils_test/test_with_reference.ts
Normal file
@@ -0,0 +1,63 @@
|
||||
import * as chai from 'chai';
|
||||
|
||||
import { chaiSetup } from '../utils/chai_setup';
|
||||
import { testWithReferenceFuncAsync } from '../utils/test_with_reference';
|
||||
|
||||
chaiSetup.configure();
|
||||
const expect = chai.expect;
|
||||
|
||||
async function divAsync(x: number, y: number): Promise<number> {
|
||||
if (y === 0) {
|
||||
throw new Error('MathError: divide by zero');
|
||||
}
|
||||
return x / y;
|
||||
}
|
||||
|
||||
// returns an async function that always returns the given value.
|
||||
function alwaysValueFunc(value: number): (x: number, y: number) => Promise<number> {
|
||||
return async (x: number, y: number) => value;
|
||||
}
|
||||
|
||||
// returns an async function which always throws/rejects with the given error
|
||||
// message.
|
||||
function alwaysFailFunc(errMessage: string): (x: number, y: number) => Promise<number> {
|
||||
return async (x: number, y: number) => {
|
||||
throw new Error(errMessage);
|
||||
};
|
||||
}
|
||||
|
||||
describe('testWithReferenceFuncAsync', () => {
|
||||
it('passes when both succeed and actual === expected', async () => {
|
||||
await testWithReferenceFuncAsync(alwaysValueFunc(0.5), divAsync, [1, 2]);
|
||||
});
|
||||
|
||||
it('passes when both fail and actual error contains expected error', async () => {
|
||||
await testWithReferenceFuncAsync(alwaysFailFunc('divide by zero'), divAsync, [1, 0]);
|
||||
});
|
||||
|
||||
it('fails when both succeed and actual !== expected', async () => {
|
||||
expect(testWithReferenceFuncAsync(alwaysValueFunc(3), divAsync, [1, 2])).to.be.rejectedWith(
|
||||
'Test case {"x":1,"y":2}: expected { value: 0.5 } to deeply equal { value: 3 }',
|
||||
);
|
||||
});
|
||||
|
||||
it('fails when both fail and actual error does not contain expected error', async () => {
|
||||
expect(
|
||||
testWithReferenceFuncAsync(alwaysFailFunc('Unexpected math error'), divAsync, [1, 0]),
|
||||
).to.be.rejectedWith(
|
||||
'MathError: divide by zero\n\tTest case: {"x":1,"y":0}: expected \'MathError: divide by zero\' to include \'Unexpected math error\'',
|
||||
);
|
||||
});
|
||||
|
||||
it('fails when referenceFunc succeeds and testFunc fails', async () => {
|
||||
expect(testWithReferenceFuncAsync(alwaysValueFunc(0), divAsync, [1, 0])).to.be.rejectedWith(
|
||||
'Test case {"x":1,"y":0}: expected { error: \'MathError: divide by zero\' } to deeply equal { value: 0 }',
|
||||
);
|
||||
});
|
||||
|
||||
it('fails when referenceFunc fails and testFunc succeeds', async () => {
|
||||
expect(testWithReferenceFuncAsync(alwaysFailFunc('divide by zero'), divAsync, [1, 2])).to.be.rejectedWith(
|
||||
'Expected error containing divide by zero but got no error\n\tTest case: {"x":1,"y":2}',
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -8,6 +8,7 @@ const baseColors = {
|
||||
greyishPink: '#E6E5E5',
|
||||
grey300: '#E0E0E0',
|
||||
beigeWhite: '#E4E4E4',
|
||||
lightBgGrey: '#EDEDED',
|
||||
grey350: '#cacaca',
|
||||
grey400: '#BDBDBD',
|
||||
lightGrey: '#BBBBBB',
|
||||
@@ -15,6 +16,7 @@ const baseColors = {
|
||||
grey: '#A5A5A5',
|
||||
darkGrey: '#818181',
|
||||
landingLinkGrey: '#919191',
|
||||
linkSectionGrey: '#999999',
|
||||
grey700: '#616161',
|
||||
grey750: '#515151',
|
||||
grey800: '#424242',
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
"@0xproject/contract-wrappers": "^0.0.5",
|
||||
"@0xproject/order-utils": "^0.0.9",
|
||||
"@0xproject/react-docs": "^1.0.7",
|
||||
"@0xproject/react-shared": "^0.2.3",
|
||||
"@0xproject/react-shared": "^1.0.8",
|
||||
"@0xproject/subproviders": "^2.0.1",
|
||||
"@0xproject/types": "^0.8.1",
|
||||
"@0xproject/typescript-typings": "^0.4.3",
|
||||
|
||||
@@ -78,5 +78,12 @@
|
||||
"WEBSITE": "网站",
|
||||
"DEVELOPERS": "首页",
|
||||
"HOME": "Rocket.chat",
|
||||
"ROCKETCHAT": "开发人员"
|
||||
"ROCKETCHAT": "开发人员",
|
||||
"BUILD_A_RELAYER": "build a relayer",
|
||||
"ETHEREUM_DEVELOPMENT": "ethereum development",
|
||||
"INTRO_TUTORIAL": "intro tutorial",
|
||||
"TRADING_TUTORIAL": "trading tutorial",
|
||||
"VIEW_ALL_DOCUMENTATION": "view all documentation",
|
||||
"SANDBOX": "0x.js sandbox",
|
||||
"GITHUB": "github"
|
||||
}
|
||||
|
||||
@@ -80,5 +80,12 @@
|
||||
"DEVELOPERS": "developers",
|
||||
"HOME": "home",
|
||||
"ROCKETCHAT": "rocket.chat",
|
||||
"TRADE_CALL_TO_ACTION": "trade on 0x"
|
||||
"TRADE_CALL_TO_ACTION": "trade on 0x",
|
||||
"BUILD_A_RELAYER": "build a relayer",
|
||||
"ETHEREUM_DEVELOPMENT": "ethereum development",
|
||||
"INTRO_TUTORIAL": "intro tutorial",
|
||||
"TRADING_TUTORIAL": "trading tutorial",
|
||||
"VIEW_ALL_DOCUMENTATION": "view all documentation",
|
||||
"SANDBOX": "0x.js sandbox",
|
||||
"GITHUB": "github"
|
||||
}
|
||||
|
||||
@@ -78,5 +78,12 @@
|
||||
"WEBSITE": "Website",
|
||||
"HOME": "홈",
|
||||
"ROCKETCHAT": "Rocket.chat",
|
||||
"DEVELOPERS": "개발자"
|
||||
"DEVELOPERS": "개발자",
|
||||
"BUILD_A_RELAYER": "build a relayer",
|
||||
"ETHEREUM_DEVELOPMENT": "ethereum development",
|
||||
"INTRO_TUTORIAL": "intro tutorial",
|
||||
"TRADING_TUTORIAL": "trading tutorial",
|
||||
"VIEW_ALL_DOCUMENTATION": "view all documentation",
|
||||
"SANDBOX": "0x.js sandbox",
|
||||
"GITHUB": "github"
|
||||
}
|
||||
|
||||
@@ -78,5 +78,12 @@
|
||||
"WEBSITE": "Веб-сайт",
|
||||
"DEVELOPERS": "Домашняя страница",
|
||||
"HOME": "Rocket.chat",
|
||||
"ROCKETCHAT": "Для разработчиков"
|
||||
"ROCKETCHAT": "Для разработчиков",
|
||||
"BUILD_A_RELAYER": "build a relayer",
|
||||
"ETHEREUM_DEVELOPMENT": "ethereum development",
|
||||
"INTRO_TUTORIAL": "intro tutorial",
|
||||
"TRADING_TUTORIAL": "trading tutorial",
|
||||
"VIEW_ALL_DOCUMENTATION": "view all documentation",
|
||||
"SANDBOX": "0x.js sandbox",
|
||||
"GITHUB": "github"
|
||||
}
|
||||
|
||||
@@ -79,5 +79,12 @@
|
||||
"WEBSITE": "website",
|
||||
"DEVELOPERS": "inicio",
|
||||
"HOME": "rocket.chat",
|
||||
"ROCKETCHAT": "desarrolladores"
|
||||
"ROCKETCHAT": "desarrolladores",
|
||||
"BUILD_A_RELAYER": "build a relayer",
|
||||
"ETHEREUM_DEVELOPMENT": "ethereum development",
|
||||
"INTRO_TUTORIAL": "intro tutorial",
|
||||
"TRADING_TUTORIAL": "trading tutorial",
|
||||
"VIEW_ALL_DOCUMENTATION": "view all documentation",
|
||||
"SANDBOX": "0x.js sandbox",
|
||||
"GITHUB": "github"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,188 @@
|
||||
import { colors } from '@0xproject/react-shared';
|
||||
import * as _ from 'lodash';
|
||||
import * as React from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { Container } from 'ts/components/ui/container';
|
||||
import { DropDown } from 'ts/components/ui/drop_down';
|
||||
import { Text } from 'ts/components/ui/text';
|
||||
import { Deco, Key, ObjectMap, WebsitePaths } from 'ts/types';
|
||||
import { constants } from 'ts/utils/constants';
|
||||
import { Translate } from 'ts/utils/translate';
|
||||
|
||||
interface LinkInfo {
|
||||
link: string;
|
||||
shouldOpenNewTab: boolean;
|
||||
}
|
||||
|
||||
const gettingStartedKeyToLinkInfo1: ObjectMap<LinkInfo> = {
|
||||
[Key.BuildARelayer]: {
|
||||
link: `${WebsitePaths.Wiki}#Build-A-Relayer`,
|
||||
shouldOpenNewTab: false,
|
||||
},
|
||||
[Key.IntroTutorial]: {
|
||||
link: `${WebsitePaths.Wiki}#Create,-Validate,-Fill-Order`,
|
||||
shouldOpenNewTab: false,
|
||||
},
|
||||
};
|
||||
const gettingStartedKeyToLinkInfo2: ObjectMap<LinkInfo> = {
|
||||
[Key.TradingTutorial]: {
|
||||
link: `${WebsitePaths.Wiki}#Find,-Submit,-Fill-Order-From-Relayer`,
|
||||
shouldOpenNewTab: false,
|
||||
},
|
||||
[Key.EthereumDevelopment]: {
|
||||
link: `${WebsitePaths.Wiki}#Ethereum-Development`,
|
||||
shouldOpenNewTab: false,
|
||||
},
|
||||
};
|
||||
const popularDocsToLinkInfos: ObjectMap<LinkInfo> = {
|
||||
[Key.ZeroExJs]: {
|
||||
link: WebsitePaths.ZeroExJs,
|
||||
shouldOpenNewTab: false,
|
||||
},
|
||||
[Key.Connect]: {
|
||||
link: WebsitePaths.Connect,
|
||||
shouldOpenNewTab: false,
|
||||
},
|
||||
[Key.SmartContract]: {
|
||||
link: WebsitePaths.SmartContracts,
|
||||
shouldOpenNewTab: false,
|
||||
},
|
||||
};
|
||||
const usefulLinksToLinkInfo: ObjectMap<LinkInfo> = {
|
||||
[Key.Github]: {
|
||||
link: constants.URL_GITHUB_ORG,
|
||||
shouldOpenNewTab: true,
|
||||
},
|
||||
[Key.Whitepaper]: {
|
||||
link: WebsitePaths.Whitepaper,
|
||||
shouldOpenNewTab: true,
|
||||
},
|
||||
[Key.Sandbox]: {
|
||||
link: constants.URL_SANDBOX,
|
||||
shouldOpenNewTab: true,
|
||||
},
|
||||
};
|
||||
|
||||
interface DevelopersDropDownProps {
|
||||
translate: Translate;
|
||||
menuItemStyles: React.CSSProperties;
|
||||
menuIconStyle: React.CSSProperties;
|
||||
}
|
||||
|
||||
interface DevelopersDropDownState {}
|
||||
|
||||
export class DevelopersDropDown extends React.Component<DevelopersDropDownProps, DevelopersDropDownState> {
|
||||
public render(): React.ReactNode {
|
||||
const activeNode = (
|
||||
<Container className="flex relative" paddingRight="10">
|
||||
<Text fontColor={this.props.menuIconStyle.color}>
|
||||
{this.props.translate.get(Key.Developers, Deco.Cap)}
|
||||
</Text>
|
||||
</Container>
|
||||
);
|
||||
return (
|
||||
<DropDown
|
||||
activeNode={activeNode}
|
||||
popoverContent={this._renderDropdownMenu()}
|
||||
anchorOrigin={{ horizontal: 'left', vertical: 'bottom' }}
|
||||
targetOrigin={{ horizontal: 'left', vertical: 'top' }}
|
||||
style={this.props.menuItemStyles}
|
||||
popoverStyle={{ borderRadius: 4, width: 427, height: 373, marginTop: 10 }}
|
||||
/>
|
||||
);
|
||||
}
|
||||
private _renderDropdownMenu(): React.ReactNode {
|
||||
const dropdownMenu = (
|
||||
<div>
|
||||
<Container padding="1.75rem">
|
||||
{this._renderTitle('Getting started')}
|
||||
<div className="flex">
|
||||
<div className="pr4 mr2">{this._renderLinkSection(gettingStartedKeyToLinkInfo1)}</div>
|
||||
<div>{this._renderLinkSection(gettingStartedKeyToLinkInfo2)}</div>
|
||||
</div>
|
||||
</Container>
|
||||
<div
|
||||
style={{
|
||||
width: '100%',
|
||||
height: 1,
|
||||
backgroundColor: colors.grey300,
|
||||
}}
|
||||
/>
|
||||
<div className="flex" style={{ padding: '1.75rem' }}>
|
||||
<div className="pr4 mr2">
|
||||
<div>{this._renderTitle('Popular docs')}</div>
|
||||
<div>{this._renderLinkSection(popularDocsToLinkInfos)}</div>
|
||||
</div>
|
||||
<div>
|
||||
<div>{this._renderTitle('Useful links')}</div>
|
||||
<div>{this._renderLinkSection(usefulLinksToLinkInfo)}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
style={{
|
||||
padding: '0.8rem',
|
||||
textAlign: 'center',
|
||||
backgroundColor: colors.lightBgGrey,
|
||||
borderBottomLeftRadius: 4,
|
||||
borderBottomRightRadius: 4,
|
||||
}}
|
||||
>
|
||||
<Link
|
||||
to={WebsitePaths.ZeroExJs}
|
||||
className="text-decoration-none"
|
||||
style={{
|
||||
color: colors.lightBlueA700,
|
||||
fontWeight: 'bold',
|
||||
fontSize: 14,
|
||||
}}
|
||||
>
|
||||
{this.props.translate.get(Key.ViewAllDocumentation, Deco.Upper)}
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
return dropdownMenu;
|
||||
}
|
||||
private _renderTitle(title: string): React.ReactNode {
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
color: colors.linkSectionGrey,
|
||||
fontSize: 14,
|
||||
paddingBottom: 12,
|
||||
fontWeight: 600,
|
||||
letterSpacing: 1,
|
||||
}}
|
||||
>
|
||||
{title.toUpperCase()}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
private _renderLinkSection(keyToLinkInfo: ObjectMap<LinkInfo>): React.ReactNode {
|
||||
const linkStyle: React.CSSProperties = {
|
||||
color: colors.lightBlueA700,
|
||||
fontFamily: 'Roboto, Roboto Mono',
|
||||
};
|
||||
const numLinks = _.size(keyToLinkInfo);
|
||||
let i = 0;
|
||||
const links = _.map(keyToLinkInfo, (linkInfo: LinkInfo, key: string) => {
|
||||
i++;
|
||||
const isLast = i === numLinks;
|
||||
const linkText = this.props.translate.get(key as Key, Deco.CapWords);
|
||||
return (
|
||||
<div className={`pr1 pt1 ${!isLast && 'pb1'}`} key={`dev-dropdown-link-${key}`}>
|
||||
{linkInfo.shouldOpenNewTab ? (
|
||||
<a target="_blank" className="text-decoration-none" style={linkStyle} href={linkInfo.link}>
|
||||
{linkText}
|
||||
</a>
|
||||
) : (
|
||||
<Link to={linkInfo.link} className="text-decoration-none" style={linkStyle}>
|
||||
{linkText}
|
||||
</Link>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
});
|
||||
return <div>{links}</div>;
|
||||
}
|
||||
}
|
||||
@@ -8,18 +8,17 @@ import {
|
||||
} from '@0xproject/react-shared';
|
||||
import * as _ from 'lodash';
|
||||
import Drawer from 'material-ui/Drawer';
|
||||
import Menu from 'material-ui/Menu';
|
||||
import MenuItem from 'material-ui/MenuItem';
|
||||
import * as React from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { Blockchain } from 'ts/blockchain';
|
||||
import { DevelopersDropDown } from 'ts/components/dropdowns/developers_drop_down';
|
||||
import { DrawerMenu } from 'ts/components/portal/drawer_menu';
|
||||
import { ProviderDisplay } from 'ts/components/top_bar/provider_display';
|
||||
import { TopBarMenuItem } from 'ts/components/top_bar/top_bar_menu_item';
|
||||
import { Container } from 'ts/components/ui/container';
|
||||
import { DropDown } from 'ts/components/ui/drop_down';
|
||||
import { Dispatcher } from 'ts/redux/dispatcher';
|
||||
import { Deco, Key, ProviderType, WebsiteLegacyPaths, WebsitePaths } from 'ts/types';
|
||||
import { Deco, Key, ProviderType, WebsitePaths } from 'ts/types';
|
||||
import { constants } from 'ts/utils/constants';
|
||||
import { Translate } from 'ts/utils/translate';
|
||||
|
||||
@@ -129,111 +128,6 @@ export class TopBar extends React.Component<TopBarProps, TopBarState> {
|
||||
? 'flex mx-auto items-center max-width-4'
|
||||
: 'flex mx-auto items-center';
|
||||
const height = isExpandedDisplayType ? EXPANDED_HEIGHT : DEFAULT_HEIGHT;
|
||||
const developerSectionMenuItems = [
|
||||
<Link key="subMenuItem-zeroEx" to={WebsitePaths.ZeroExJs} className="text-decoration-none">
|
||||
<MenuItem style={{ fontSize: styles.menuItem.fontSize }} primaryText="0x.js" />
|
||||
</Link>,
|
||||
<Link key="subMenuItem-smartContracts" to={WebsitePaths.SmartContracts} className="text-decoration-none">
|
||||
<MenuItem
|
||||
style={{ fontSize: styles.menuItem.fontSize }}
|
||||
primaryText={this.props.translate.get(Key.SmartContract, Deco.CapWords)}
|
||||
/>
|
||||
</Link>,
|
||||
<Link key="subMenuItem-0xconnect" to={WebsitePaths.Connect} className="text-decoration-none">
|
||||
<MenuItem
|
||||
style={{ fontSize: styles.menuItem.fontSize }}
|
||||
primaryText={this.props.translate.get(Key.Connect, Deco.CapWords)}
|
||||
/>
|
||||
</Link>,
|
||||
<a
|
||||
key="subMenuItem-standard-relayer-api"
|
||||
target="_blank"
|
||||
className="text-decoration-none"
|
||||
href={constants.URL_STANDARD_RELAYER_API_GITHUB}
|
||||
>
|
||||
<MenuItem
|
||||
style={{ fontSize: styles.menuItem.fontSize }}
|
||||
primaryText={this.props.translate.get(Key.StandardRelayerApi, Deco.CapWords)}
|
||||
/>
|
||||
</a>,
|
||||
<Link key="subMenuItem-jsonSchema" to={WebsitePaths.JSONSchemas} className="text-decoration-none">
|
||||
<MenuItem
|
||||
style={{ fontSize: styles.menuItem.fontSize }}
|
||||
primaryText={this.props.translate.get(Key.JsonSchemas, Deco.CapWords)}
|
||||
/>
|
||||
</Link>,
|
||||
<Link key="subMenuItem-subproviders" to={WebsitePaths.Subproviders} className="text-decoration-none">
|
||||
<MenuItem
|
||||
style={{ fontSize: styles.menuItem.fontSize }}
|
||||
primaryText={this.props.translate.get(Key.Subproviders, Deco.CapWords)}
|
||||
/>
|
||||
</Link>,
|
||||
<Link key="subMenuItem-web3Wrapper" to={WebsitePaths.Web3Wrapper} className="text-decoration-none">
|
||||
<MenuItem
|
||||
style={{ fontSize: styles.menuItem.fontSize }}
|
||||
primaryText={this.props.translate.get(Key.Web3Wrapper, Deco.CapWords)}
|
||||
/>
|
||||
</Link>,
|
||||
<Link
|
||||
key="subMenuItem-contractWrappers"
|
||||
to={WebsitePaths.ContractWrappers}
|
||||
className="text-decoration-none"
|
||||
>
|
||||
<MenuItem
|
||||
style={{ fontSize: styles.menuItem.fontSize }}
|
||||
primaryText={this.props.translate.get(Key.ContractWrappers, Deco.CapWords)}
|
||||
/>
|
||||
</Link>,
|
||||
<Link key="subMenuItem-orderUtils" to={WebsitePaths.OrderUtils} className="text-decoration-none">
|
||||
<MenuItem
|
||||
style={{ fontSize: styles.menuItem.fontSize }}
|
||||
primaryText={this.props.translate.get(Key.OrderUtils, Deco.CapWords)}
|
||||
/>
|
||||
</Link>,
|
||||
<Link key="subMenuItem-orderWatcher" to={WebsitePaths.OrderWatcher} className="text-decoration-none">
|
||||
<MenuItem
|
||||
style={{ fontSize: styles.menuItem.fontSize }}
|
||||
primaryText={this.props.translate.get(Key.OrderWatcher, Deco.CapWords)}
|
||||
/>
|
||||
</Link>,
|
||||
<Link key="subMenuItem-sol-compiler" to={WebsitePaths.SolCompiler} className="text-decoration-none">
|
||||
<MenuItem
|
||||
style={{ fontSize: styles.menuItem.fontSize }}
|
||||
primaryText={this.props.translate.get(Key.SolCompiler, Deco.CapWords)}
|
||||
/>
|
||||
</Link>,
|
||||
<Link key="subMenuItem-sol-cov" to={WebsitePaths.SolCov} className="text-decoration-none">
|
||||
<MenuItem
|
||||
style={{ fontSize: styles.menuItem.fontSize }}
|
||||
primaryText={this.props.translate.get(Key.SolCov, Deco.CapWords)}
|
||||
/>
|
||||
</Link>,
|
||||
<Link key="subMenuItem-ethereum-types" to={WebsitePaths.EthereumTypes} className="text-decoration-none">
|
||||
<MenuItem
|
||||
style={{ fontSize: styles.menuItem.fontSize }}
|
||||
primaryText={this.props.translate.get(Key.EthereumTypes, Deco.CapWords)}
|
||||
/>
|
||||
</Link>,
|
||||
<a
|
||||
key="subMenuItem-whitePaper"
|
||||
target="_blank"
|
||||
className="text-decoration-none"
|
||||
href={`${WebsitePaths.Whitepaper}`}
|
||||
>
|
||||
<MenuItem
|
||||
style={{ fontSize: styles.menuItem.fontSize }}
|
||||
primaryText={this.props.translate.get(Key.Whitepaper, Deco.CapWords)}
|
||||
/>
|
||||
</a>,
|
||||
<a
|
||||
key="subMenuItem-github"
|
||||
target="_blank"
|
||||
className="text-decoration-none"
|
||||
href={constants.URL_GITHUB_ORG}
|
||||
>
|
||||
<MenuItem style={{ fontSize: styles.menuItem.fontSize }} primaryText="GitHub" />
|
||||
</a>,
|
||||
];
|
||||
const bottomBorderStyle = this._shouldDisplayBottomBar() ? styles.bottomBar : {};
|
||||
const fullWidthClasses = isExpandedDisplayType ? 'pr4' : '';
|
||||
const logoUrl = isNightVersion ? '/images/protocol_logo_white.png' : '/images/protocol_logo_black.png';
|
||||
@@ -245,15 +139,6 @@ export class TopBar extends React.Component<TopBarProps, TopBarState> {
|
||||
color: isNightVersion ? 'white' : 'black',
|
||||
cursor: 'pointer',
|
||||
};
|
||||
const activeNode = (
|
||||
<div className="flex relative" style={{ color: menuIconStyle.color }}>
|
||||
<div style={{ paddingRight: 10 }}>{this.props.translate.get(Key.Developers, Deco.Cap)}</div>
|
||||
<div className="absolute" style={{ paddingLeft: 3, right: 3, top: -2 }}>
|
||||
<i className="zmdi zmdi-caret-right" style={{ fontSize: 22 }} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
const popoverContent = <Menu style={{ color: colors.darkGrey }}>{developerSectionMenuItems}</Menu>;
|
||||
return (
|
||||
<div
|
||||
style={{ ...styles.topBar, ...bottomBorderStyle, ...this.props.style, ...{ height } }}
|
||||
@@ -273,12 +158,10 @@ export class TopBar extends React.Component<TopBarProps, TopBarState> {
|
||||
{!this._isViewingPortal() && (
|
||||
<div className={menuClasses}>
|
||||
<div className="flex items-center justify-between">
|
||||
<DropDown
|
||||
activeNode={activeNode}
|
||||
popoverContent={popoverContent}
|
||||
anchorOrigin={{ horizontal: 'middle', vertical: 'bottom' }}
|
||||
targetOrigin={{ horizontal: 'middle', vertical: 'top' }}
|
||||
style={styles.menuItem}
|
||||
<DevelopersDropDown
|
||||
menuItemStyles={styles.menuItem}
|
||||
translate={this.props.translate}
|
||||
menuIconStyle={menuIconStyle}
|
||||
/>
|
||||
<TopBarMenuItem
|
||||
title={this.props.translate.get(Key.Wiki, Deco.Cap)}
|
||||
|
||||
@@ -21,6 +21,7 @@ export interface DropDownProps {
|
||||
zDepth?: number;
|
||||
activateEvent?: DropdownMouseEvent;
|
||||
closeEvent?: DropdownMouseEvent;
|
||||
popoverStyle?: React.CSSProperties;
|
||||
}
|
||||
|
||||
interface DropDownState {
|
||||
@@ -34,6 +35,7 @@ export class DropDown extends React.Component<DropDownProps, DropDownState> {
|
||||
zDepth: 1,
|
||||
activateEvent: DropdownMouseEvent.Hover,
|
||||
closeEvent: DropdownMouseEvent.Hover,
|
||||
popoverStyle: {},
|
||||
};
|
||||
private _isHovering: boolean;
|
||||
private _popoverCloseCheckIntervalId: number;
|
||||
@@ -77,6 +79,7 @@ export class DropDown extends React.Component<DropDownProps, DropDownState> {
|
||||
useLayerForClickAway={this.props.closeEvent === DropdownMouseEvent.Click}
|
||||
animated={false}
|
||||
zDepth={this.props.zDepth}
|
||||
style={this.props.popoverStyle}
|
||||
>
|
||||
<div
|
||||
onMouseEnter={this._onHover.bind(this)}
|
||||
|
||||
@@ -468,6 +468,13 @@ export enum Key {
|
||||
Home = 'HOME',
|
||||
RocketChat = 'ROCKETCHAT',
|
||||
TradeCallToAction = 'TRADE_CALL_TO_ACTION',
|
||||
BuildARelayer = 'BUILD_A_RELAYER',
|
||||
EthereumDevelopment = 'ETHEREUM_DEVELOPMENT',
|
||||
IntroTutorial = 'INTRO_TUTORIAL',
|
||||
TradingTutorial = 'TRADING_TUTORIAL',
|
||||
ViewAllDocumentation = 'VIEW_ALL_DOCUMENTATION',
|
||||
Sandbox = 'SANDBOX',
|
||||
Github = 'GITHUB',
|
||||
}
|
||||
|
||||
export enum SmartContractDocSections {
|
||||
|
||||
@@ -83,6 +83,7 @@ export const constants = {
|
||||
URL_PARITY_CHROME_STORE:
|
||||
'https://chrome.google.com/webstore/detail/parity-ethereum-integrati/himekenlppkgeaoeddcliojfddemadig',
|
||||
URL_REDDIT: 'https://reddit.com/r/0xproject',
|
||||
URL_SANDBOX: 'https://codesandbox.io/s/1qmjyp7p5j',
|
||||
URL_STANDARD_RELAYER_API_GITHUB: 'https://github.com/0xProject/standard-relayer-api/blob/master/README.md',
|
||||
URL_TWITTER: 'https://twitter.com/0xproject',
|
||||
URL_WETH_IO: 'https://weth.io/',
|
||||
|
||||
@@ -80,7 +80,12 @@ export class Translate {
|
||||
|
||||
case Deco.CapWords:
|
||||
const words = text.split(' ');
|
||||
const capitalizedWords = _.map(words, w => this._capitalize(w));
|
||||
const capitalizedWords = _.map(words, (w: string, i: number) => {
|
||||
if (w.length === 1) {
|
||||
return w;
|
||||
}
|
||||
return this._capitalize(w);
|
||||
});
|
||||
text = capitalizedWords.join(' ');
|
||||
break;
|
||||
|
||||
|
||||
106
yarn.lock
106
yarn.lock
@@ -704,27 +704,6 @@
|
||||
ethers "3.0.22"
|
||||
lodash "4.17.10"
|
||||
|
||||
"@0xproject/react-shared@^0.2.3":
|
||||
version "0.2.3"
|
||||
resolved "https://registry.yarnpkg.com/@0xproject/react-shared/-/react-shared-0.2.3.tgz#f0403b9b7f1cfbe2853b53cc983ebb13ee8753a5"
|
||||
dependencies:
|
||||
"@types/lodash" "4.14.104"
|
||||
"@types/material-ui" "0.18.0"
|
||||
"@types/node" "9.6.0"
|
||||
"@types/react" "16.3.13"
|
||||
"@types/react-dom" "16.0.4"
|
||||
"@types/react-scroll" "0.0.31"
|
||||
basscss "8.0.4"
|
||||
is-mobile "0.2.2"
|
||||
lodash "4.17.10"
|
||||
material-ui "0.17.4"
|
||||
react "15.6.1"
|
||||
react-dom "15.6.1"
|
||||
react-highlight "0xproject/react-highlight"
|
||||
react-markdown "3.2.2"
|
||||
react-scroll "1.7.7"
|
||||
react-tap-event-plugin "2.0.1"
|
||||
|
||||
"@0xproject/sol-compiler@^0.5.3", "@0xproject/sol-compiler@^0.5.4":
|
||||
version "0.5.4"
|
||||
resolved "https://registry.yarnpkg.com/@0xproject/sol-compiler/-/sol-compiler-0.5.4.tgz#3e0b04b0c02c5ec046ebb962b5ed20978c6b4cdd"
|
||||
@@ -1158,13 +1137,6 @@
|
||||
"@types/node" "*"
|
||||
"@types/react" "*"
|
||||
|
||||
"@types/react-dom@16.0.4":
|
||||
version "16.0.4"
|
||||
resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-16.0.4.tgz#2e8fd45f5443780ed49bf2cdd9809e6091177a7d"
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
"@types/react" "*"
|
||||
|
||||
"@types/react-dom@^16.0.3":
|
||||
version "16.0.5"
|
||||
resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-16.0.5.tgz#a757457662e3819409229e8f86795ff37b371f96"
|
||||
@@ -1200,12 +1172,6 @@
|
||||
"@types/history" "*"
|
||||
"@types/react" "*"
|
||||
|
||||
"@types/react-scroll@0.0.31":
|
||||
version "0.0.31"
|
||||
resolved "https://registry.yarnpkg.com/@types/react-scroll/-/react-scroll-0.0.31.tgz#1bb26bfd9f595da6403c2f13c2f9a3ed4d2929fa"
|
||||
dependencies:
|
||||
"@types/react" "*"
|
||||
|
||||
"@types/react-scroll@1.5.3":
|
||||
version "1.5.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/react-scroll/-/react-scroll-1.5.3.tgz#cc4e94db3d7d5b1cd244bfee24091c335d3e2598"
|
||||
@@ -2539,7 +2505,7 @@ basscss-typography@^3.0.4:
|
||||
version "3.0.4"
|
||||
resolved "https://registry.yarnpkg.com/basscss-typography/-/basscss-typography-3.0.4.tgz#ec946a2bad8dd1af97be9ea108ad4bb7be932464"
|
||||
|
||||
basscss@8.0.4, basscss@^8.0.3:
|
||||
basscss@^8.0.3:
|
||||
version "8.0.4"
|
||||
resolved "https://registry.yarnpkg.com/basscss/-/basscss-8.0.4.tgz#b371a2ce25aeb9b322302f37f4e425753dd29ae1"
|
||||
dependencies:
|
||||
@@ -7438,7 +7404,7 @@ is-lower-case@^1.1.0:
|
||||
dependencies:
|
||||
lower-case "^1.1.0"
|
||||
|
||||
is-mobile@0.2.2, is-mobile@^0.2.2:
|
||||
is-mobile@^0.2.2:
|
||||
version "0.2.2"
|
||||
resolved "https://registry.yarnpkg.com/is-mobile/-/is-mobile-0.2.2.tgz#0e2e006d99ed2c2155b761df80f2a3619ae2ad9f"
|
||||
|
||||
@@ -8759,7 +8725,7 @@ marked@^0.4.0:
|
||||
version "0.4.0"
|
||||
resolved "https://registry.yarnpkg.com/marked/-/marked-0.4.0.tgz#9ad2c2a7a1791f10a852e0112f77b571dce10c66"
|
||||
|
||||
material-ui@0.17.4, material-ui@^0.17.1:
|
||||
material-ui@^0.17.1:
|
||||
version "0.17.4"
|
||||
resolved "https://registry.yarnpkg.com/material-ui/-/material-ui-0.17.4.tgz#193999ecb49c3ec15ae0abb4e90fdf9a7bd343e0"
|
||||
dependencies:
|
||||
@@ -10110,17 +10076,6 @@ parse-asn1@^5.0.0:
|
||||
evp_bytestokey "^1.0.0"
|
||||
pbkdf2 "^3.0.3"
|
||||
|
||||
parse-entities@^1.0.2:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/parse-entities/-/parse-entities-1.1.2.tgz#9eaf719b29dc3bd62246b4332009072e01527777"
|
||||
dependencies:
|
||||
character-entities "^1.0.0"
|
||||
character-entities-legacy "^1.0.0"
|
||||
character-reference-invalid "^1.0.0"
|
||||
is-alphanumerical "^1.0.0"
|
||||
is-decimal "^1.0.0"
|
||||
is-hexadecimal "^1.0.0"
|
||||
|
||||
parse-entities@^1.1.0:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/parse-entities/-/parse-entities-1.1.1.tgz#8112d88471319f27abae4d64964b122fe4e1b890"
|
||||
@@ -11280,16 +11235,6 @@ react-lifecycles-compat@^3.0.2, react-lifecycles-compat@^3.0.4:
|
||||
version "3.0.4"
|
||||
resolved "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362"
|
||||
|
||||
react-markdown@3.2.2:
|
||||
version "3.2.2"
|
||||
resolved "https://registry.yarnpkg.com/react-markdown/-/react-markdown-3.2.2.tgz#439774c14f25eb25d1b96c126f28ca1486fb0a24"
|
||||
dependencies:
|
||||
prop-types "^15.6.0"
|
||||
remark-parse "^4.0.0"
|
||||
unified "^6.1.5"
|
||||
unist-util-visit "^1.1.3"
|
||||
xtend "^4.0.1"
|
||||
|
||||
react-markdown@^3.2.2:
|
||||
version "3.3.0"
|
||||
resolved "https://registry.yarnpkg.com/react-markdown/-/react-markdown-3.3.0.tgz#a87cdd822aa9302d6add9687961dd1a82a45d02e"
|
||||
@@ -11352,13 +11297,6 @@ react-scroll@0xproject/react-scroll#similar-to-pr-330:
|
||||
lodash.throttle "^4.1.1"
|
||||
prop-types "^15.5.8"
|
||||
|
||||
react-scroll@1.7.7:
|
||||
version "1.7.7"
|
||||
resolved "https://registry.yarnpkg.com/react-scroll/-/react-scroll-1.7.7.tgz#948c40c9a189b62bf4a53ee0fd50e5d89d37260a"
|
||||
dependencies:
|
||||
lodash.throttle "^4.1.1"
|
||||
prop-types "^15.5.8"
|
||||
|
||||
react-side-effect@^1.0.2, react-side-effect@^1.1.0:
|
||||
version "1.1.5"
|
||||
resolved "https://registry.yarnpkg.com/react-side-effect/-/react-side-effect-1.1.5.tgz#f26059e50ed9c626d91d661b9f3c8bb38cd0ff2d"
|
||||
@@ -11373,7 +11311,7 @@ react-tabs@^2.0.0:
|
||||
classnames "^2.2.0"
|
||||
prop-types "^15.5.0"
|
||||
|
||||
react-tap-event-plugin@2.0.1, react-tap-event-plugin@^2.0.1:
|
||||
react-tap-event-plugin@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/react-tap-event-plugin/-/react-tap-event-plugin-2.0.1.tgz#316beb3bc6556e29ec869a7293e89c826a9074d2"
|
||||
dependencies:
|
||||
@@ -11761,26 +11699,6 @@ regjsparser@^0.1.4:
|
||||
dependencies:
|
||||
jsesc "~0.5.0"
|
||||
|
||||
remark-parse@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/remark-parse/-/remark-parse-4.0.0.tgz#99f1f049afac80382366e2e0d0bd55429dd45d8b"
|
||||
dependencies:
|
||||
collapse-white-space "^1.0.2"
|
||||
is-alphabetical "^1.0.0"
|
||||
is-decimal "^1.0.0"
|
||||
is-whitespace-character "^1.0.0"
|
||||
is-word-character "^1.0.0"
|
||||
markdown-escapes "^1.0.0"
|
||||
parse-entities "^1.0.2"
|
||||
repeat-string "^1.5.4"
|
||||
state-toggle "^1.0.0"
|
||||
trim "0.0.1"
|
||||
trim-trailing-lines "^1.0.0"
|
||||
unherit "^1.0.4"
|
||||
unist-util-remove-position "^1.0.0"
|
||||
vfile-location "^2.0.0"
|
||||
xtend "^4.0.1"
|
||||
|
||||
remark-parse@^5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/remark-parse/-/remark-parse-5.0.0.tgz#4c077f9e499044d1d5c13f80d7a98cf7b9285d95"
|
||||
@@ -14128,10 +14046,6 @@ unist-util-is@^2.1.1:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/unist-util-is/-/unist-util-is-2.1.1.tgz#0c312629e3f960c66e931e812d3d80e77010947b"
|
||||
|
||||
unist-util-is@^2.1.2:
|
||||
version "2.1.2"
|
||||
resolved "https://registry.yarnpkg.com/unist-util-is/-/unist-util-is-2.1.2.tgz#1193fa8f2bfbbb82150633f3a8d2eb9a1c1d55db"
|
||||
|
||||
unist-util-remove-position@^1.0.0:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/unist-util-remove-position/-/unist-util-remove-position-1.1.1.tgz#5a85c1555fc1ba0c101b86707d15e50fa4c871bb"
|
||||
@@ -14142,24 +14056,12 @@ unist-util-stringify-position@^1.0.0, unist-util-stringify-position@^1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/unist-util-stringify-position/-/unist-util-stringify-position-1.1.1.tgz#3ccbdc53679eed6ecf3777dd7f5e3229c1b6aa3c"
|
||||
|
||||
unist-util-visit-parents@^2.0.0:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/unist-util-visit-parents/-/unist-util-visit-parents-2.0.1.tgz#63fffc8929027bee04bfef7d2cce474f71cb6217"
|
||||
dependencies:
|
||||
unist-util-is "^2.1.2"
|
||||
|
||||
unist-util-visit@^1.1.0, unist-util-visit@^1.3.0:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/unist-util-visit/-/unist-util-visit-1.3.0.tgz#41ca7c82981fd1ce6c762aac397fc24e35711444"
|
||||
dependencies:
|
||||
unist-util-is "^2.1.1"
|
||||
|
||||
unist-util-visit@^1.1.3:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/unist-util-visit/-/unist-util-visit-1.4.0.tgz#1cb763647186dc26f5e1df5db6bd1e48b3cc2fb1"
|
||||
dependencies:
|
||||
unist-util-visit-parents "^2.0.0"
|
||||
|
||||
universalify@^0.1.0:
|
||||
version "0.1.1"
|
||||
resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.1.tgz#fa71badd4437af4c148841e3b3b165f9e9e590b7"
|
||||
|
||||
Reference in New Issue
Block a user