Merge branch 'development' of github.com:0xProject/0x-monorepo into instant-callback-done
This commit is contained in:
BIN
packages/website/public/images/launch_kit/NFT_screenshot.png
Normal file
BIN
packages/website/public/images/launch_kit/NFT_screenshot.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 861 KiB |
BIN
packages/website/public/images/launch_kit/background_marquee.png
Normal file
BIN
packages/website/public/images/launch_kit/background_marquee.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.0 MiB |
BIN
packages/website/public/images/launch_kit/relayer_screenshot.png
Normal file
BIN
packages/website/public/images/launch_kit/relayer_screenshot.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 495 KiB |
150
packages/website/ts/components/background_marquee.tsx
Normal file
150
packages/website/ts/components/background_marquee.tsx
Normal file
@@ -0,0 +1,150 @@
|
||||
import React from 'react';
|
||||
import styled, { keyframes } from 'styled-components';
|
||||
|
||||
const scrollFactory = (height: number, imgRepeatCt: number) => keyframes`
|
||||
0% { transform: translate3d(0, -${height}px, 0) }
|
||||
100% { transform: translate3d(0, -${height * (imgRepeatCt - 1)}px, 0) }
|
||||
`;
|
||||
|
||||
const scrollMobileFactory = (height: number, imgRepeatCt: number) => keyframes`
|
||||
0% { transform: translate3d(0, -${height}px, 0) }
|
||||
100% { transform: translate3d(0, -${height * (imgRepeatCt - 1)}px, 0) }
|
||||
`;
|
||||
|
||||
interface MarqueeWrapProps {
|
||||
height?: string;
|
||||
imgHeightInPx: number;
|
||||
imgRepeatCt: number;
|
||||
}
|
||||
|
||||
const MarqueeWrap = styled.div<MarqueeWrapProps>`
|
||||
width: 130%;
|
||||
margin-left: -15%;
|
||||
margin-right: -15%;
|
||||
height: ${props => props.height || '100%'};
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
|
||||
&:after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: ${props => props.height || '100%'};
|
||||
left: 0;
|
||||
top: 0;
|
||||
background: linear-gradient(180.18deg, #000000 11.09%, rgba(0, 0, 0, 0.8) 62.74%, rgba(0, 0, 0, 0) 103.8%);
|
||||
}
|
||||
|
||||
&:before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
height: 4rem;
|
||||
left: -2rem;
|
||||
right: -2rem;
|
||||
bottom: -2rem;
|
||||
filter: blur(1rem);
|
||||
z-index: 1;
|
||||
background: #000;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
> div {
|
||||
height: auto;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
will-change: transform;
|
||||
transform: translate3d(0, -${props => props.imgHeightInPx}px, 0);
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
> div {
|
||||
height: ${props => props.imgHeightInPx * props.imgRepeatCt}px;
|
||||
animation: ${props => scrollFactory(props.imgHeightInPx, props.imgRepeatCt)} 140s linear infinite;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
> div {
|
||||
height: ${props => props.imgHeightInPx * props.imgRepeatCt}px;
|
||||
animation: ${props => scrollMobileFactory(props.imgHeightInPx, props.imgRepeatCt)} 140s linear infinite;
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
interface CardProps {}
|
||||
|
||||
const Card = styled.div<CardProps>`
|
||||
opacity: 1;
|
||||
will-change: opacity, transform;
|
||||
|
||||
& + & {
|
||||
margin-top: -0px;
|
||||
}
|
||||
|
||||
img {
|
||||
height: auto;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
img {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
img {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const MarqueeImg = styled.img`
|
||||
object-fit: cover;
|
||||
opacity: 1;
|
||||
`;
|
||||
|
||||
export interface BackgroundMarqueeProps {
|
||||
height?: string;
|
||||
imgSrcUrl: string;
|
||||
}
|
||||
|
||||
export class BackgroundMarquee extends React.Component<BackgroundMarqueeProps> {
|
||||
public state = {
|
||||
imgRepeatCt: 3,
|
||||
imgHeightInPx: 2000,
|
||||
};
|
||||
|
||||
private _imageRef: HTMLImageElement;
|
||||
|
||||
public render(): React.ReactNode {
|
||||
return (
|
||||
<MarqueeWrap
|
||||
height={this.props.height}
|
||||
imgHeightInPx={this.state.imgHeightInPx}
|
||||
imgRepeatCt={this.state.imgRepeatCt}
|
||||
>
|
||||
<div>
|
||||
{[...Array(this.state.imgRepeatCt)].map((item, index) => (
|
||||
<Card key={`card-${index}`}>
|
||||
<MarqueeImg
|
||||
onLoad={index === 0 ? this._onImageUpdate : null}
|
||||
ref={ref => (index === 0 ? (this._imageRef = ref) : null)}
|
||||
src={this.props.imgSrcUrl}
|
||||
alt=""
|
||||
/>
|
||||
</Card>
|
||||
))}
|
||||
</div>
|
||||
</MarqueeWrap>
|
||||
);
|
||||
}
|
||||
|
||||
private readonly _onImageUpdate = () => {
|
||||
if (!!this._imageRef) {
|
||||
this.setState({ imgHeightInPx: this._imageRef.clientHeight });
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -11,6 +11,7 @@ export interface ButtonInterface {
|
||||
isDisabled?: boolean;
|
||||
className?: string;
|
||||
bgColor?: string;
|
||||
transparentBgColor?: string;
|
||||
borderColor?: string;
|
||||
color?: string;
|
||||
children?: React.ReactNode | string;
|
||||
@@ -69,7 +70,8 @@ const ButtonBase = styled.button<ButtonInterface>`
|
||||
border: 1px solid transparent;
|
||||
display: inline-block;
|
||||
background-color: ${props => props.bgColor || colors.brandLight};
|
||||
background-color: ${props => (props.isTransparent || props.isWithArrow) && 'transparent'};
|
||||
background-color: ${props =>
|
||||
(props.isTransparent || props.isWithArrow) && (props.transparentBgColor || 'transparent')};
|
||||
border-color: ${props => props.isTransparent && !props.isWithArrow && props.borderColor};
|
||||
color: ${props => (props.isAccentColor ? props.theme.linkColor : props.color || props.theme.textColor)};
|
||||
padding: ${props =>
|
||||
|
||||
37
packages/website/ts/components/checkmark_list.tsx
Normal file
37
packages/website/ts/components/checkmark_list.tsx
Normal file
@@ -0,0 +1,37 @@
|
||||
import * as React from 'react';
|
||||
import styled from 'styled-components';
|
||||
|
||||
export const CheckedUl = styled.ul`
|
||||
list-style-type: none;
|
||||
`;
|
||||
|
||||
const Li = styled.li`
|
||||
padding: 0.8rem 0 0.8rem 1.5rem;
|
||||
position: relative;
|
||||
line-height: 1.4rem;
|
||||
#checkmark-icon {
|
||||
position: absolute;
|
||||
top: 1rem;
|
||||
left: 0;
|
||||
}
|
||||
@media (max-width: 768px) {
|
||||
font-size: 15px;
|
||||
}
|
||||
`;
|
||||
|
||||
const Checkmark = () => (
|
||||
<svg id="checkmark-icon" width="18" height="13" viewBox="0 0 18 13" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M17 1L6 12L1 7" stroke="#00AE99" stroke-width="1.4" />
|
||||
</svg>
|
||||
);
|
||||
|
||||
interface CheckedLiProps {
|
||||
children: string;
|
||||
}
|
||||
|
||||
export const CheckedLi = (props: CheckedLiProps) => (
|
||||
<Li>
|
||||
<Checkmark />
|
||||
{props.children}
|
||||
</Li>
|
||||
);
|
||||
@@ -17,7 +17,7 @@ interface Props {
|
||||
isInlineIcon?: boolean;
|
||||
isCentered?: boolean;
|
||||
isWithMargin?: boolean;
|
||||
icon: string;
|
||||
icon?: string;
|
||||
iconSize?: 'medium' | 'large' | number;
|
||||
fontSize?: 'default' | 'medium' | number;
|
||||
title: string;
|
||||
@@ -28,7 +28,7 @@ interface Props {
|
||||
|
||||
export const Definition = (props: Props) => (
|
||||
<Wrap {...props}>
|
||||
<Icon name={props.icon} size={props.iconSize || 'medium'} margin={[0, 0, 'default', 0]} />
|
||||
{!!props.icon && <Icon name={props.icon} size={props.iconSize || 'medium'} margin={[0, 0, 'default', 0]} />}
|
||||
|
||||
<TextWrap {...props}>
|
||||
<Heading
|
||||
|
||||
@@ -38,12 +38,12 @@ const introData: LinkConfig[] = [
|
||||
url: `${WebsitePaths.Wiki}#Find,-Submit,-Fill-Order-From-Relayer`,
|
||||
},
|
||||
{
|
||||
label: 'Market making',
|
||||
url: `${WebsitePaths.MarketMaker}`,
|
||||
label: 'Use 0x Instant',
|
||||
url: `${WebsitePaths.Wiki}#Get-Started-With-Instant`,
|
||||
},
|
||||
{
|
||||
label: 'Free credits',
|
||||
url: `${WebsitePaths.Credits}`,
|
||||
label: '0x Code Sandbox',
|
||||
url: constants.URL_SANDBOX,
|
||||
},
|
||||
];
|
||||
|
||||
|
||||
100
packages/website/ts/components/dropdowns/dropdown_resources.tsx
Normal file
100
packages/website/ts/components/dropdowns/dropdown_resources.tsx
Normal file
@@ -0,0 +1,100 @@
|
||||
import { Link } from '@0x/react-shared';
|
||||
import * as _ from 'lodash';
|
||||
import * as React from 'react';
|
||||
import styled, { withTheme } from 'styled-components';
|
||||
|
||||
import { Column, FlexWrap } from 'ts/components/newLayout';
|
||||
import { ThemeValuesInterface } from 'ts/components/siteWrap';
|
||||
import { Heading } from 'ts/components/text';
|
||||
import { WebsitePaths } from 'ts/types';
|
||||
import { constants } from 'ts/utils/constants';
|
||||
|
||||
interface Props {
|
||||
theme: ThemeValuesInterface;
|
||||
}
|
||||
|
||||
interface LinkConfig {
|
||||
label: string;
|
||||
url: string;
|
||||
shouldOpenInNewTab?: boolean;
|
||||
}
|
||||
|
||||
const introData: LinkConfig[] = [
|
||||
{
|
||||
label: 'Blog',
|
||||
url: constants.URL_BLOG,
|
||||
shouldOpenInNewTab: true,
|
||||
},
|
||||
{
|
||||
label: 'Legal Wiki',
|
||||
url: `${WebsitePaths.Wiki}#Legal-Wiki`,
|
||||
shouldOpenInNewTab: true,
|
||||
},
|
||||
];
|
||||
|
||||
const programsData: LinkConfig[] = [
|
||||
{
|
||||
label: 'Ecosystem Grants',
|
||||
url: WebsitePaths.Ecosystem,
|
||||
},
|
||||
{
|
||||
label: 'Market Making',
|
||||
url: WebsitePaths.MarketMaker,
|
||||
},
|
||||
{
|
||||
label: 'Infrastructure Credits',
|
||||
url: WebsitePaths.Credits,
|
||||
},
|
||||
];
|
||||
|
||||
export const DropdownResources: React.FunctionComponent<Props> = withTheme((props: Props) => (
|
||||
<>
|
||||
<DropdownWrap>
|
||||
<ul>
|
||||
{_.map(introData, (item, index) => (
|
||||
<li key={`introLink-${index}`}>
|
||||
<Link to={item.url} shouldOpenInNewTab={item.shouldOpenInNewTab}>
|
||||
{item.label}
|
||||
</Link>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
|
||||
<StyledWrap>
|
||||
<Column width="calc(100% - 15px)">
|
||||
<Heading asElement="h4" size={14} color="inherit" marginBottom="15px" isMuted={0.35}>
|
||||
Programs
|
||||
</Heading>
|
||||
|
||||
<ul>
|
||||
{_.map(programsData, (item, index) => (
|
||||
<li key={`programsLink-${index}`}>
|
||||
<Link to={item.url} shouldOpenInNewTab={item.shouldOpenInNewTab}>
|
||||
{item.label}
|
||||
</Link>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</Column>
|
||||
</StyledWrap>
|
||||
</DropdownWrap>
|
||||
</>
|
||||
));
|
||||
|
||||
const DropdownWrap = styled.div`
|
||||
padding: 15px 30px 0 30px;
|
||||
|
||||
a {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
ul li {
|
||||
margin: 0 0 16px 0;
|
||||
}
|
||||
`;
|
||||
|
||||
const StyledWrap = styled(FlexWrap)`
|
||||
padding-top: 20px;
|
||||
margin-top: 10px;
|
||||
position: relative;
|
||||
`;
|
||||
@@ -9,13 +9,13 @@ import Headroom from 'react-headroom';
|
||||
import { Button } from 'ts/components/button';
|
||||
import { DropdownDevelopers } from 'ts/components/dropdowns/dropdown_developers';
|
||||
import { DropdownProducts } from 'ts/components/dropdowns/dropdown_products';
|
||||
import { DropdownResources } from 'ts/components/dropdowns/dropdown_resources';
|
||||
import { Hamburger } from 'ts/components/hamburger';
|
||||
import { Logo } from 'ts/components/logo';
|
||||
import { MobileNav } from 'ts/components/mobileNav';
|
||||
import { FlexWrap } from 'ts/components/newLayout';
|
||||
import { ThemeValuesInterface } from 'ts/components/siteWrap';
|
||||
import { WebsitePaths } from 'ts/types';
|
||||
import { constants } from 'ts/utils/constants';
|
||||
|
||||
interface HeaderProps {
|
||||
location?: Location;
|
||||
@@ -30,7 +30,6 @@ interface NavItemProps {
|
||||
text?: string;
|
||||
dropdownWidth?: number;
|
||||
dropdownComponent?: React.FunctionComponent<any>;
|
||||
shouldOpenInNewTab?: boolean;
|
||||
}
|
||||
|
||||
interface DropdownWrapInterface {
|
||||
@@ -55,17 +54,17 @@ const navItems: NavItemProps[] = [
|
||||
dropdownComponent: DropdownDevelopers,
|
||||
dropdownWidth: 480,
|
||||
},
|
||||
{
|
||||
id: 'resources',
|
||||
text: 'Resources',
|
||||
dropdownComponent: DropdownResources,
|
||||
dropdownWidth: 270,
|
||||
},
|
||||
{
|
||||
id: 'about',
|
||||
url: WebsitePaths.AboutMission,
|
||||
text: 'About',
|
||||
},
|
||||
{
|
||||
id: 'blog',
|
||||
url: constants.URL_BLOG,
|
||||
shouldOpenInNewTab: true,
|
||||
text: 'Blog',
|
||||
},
|
||||
];
|
||||
|
||||
class HeaderBase extends React.Component<HeaderProps> {
|
||||
@@ -121,9 +120,7 @@ const NavItem = (props: { link: NavItemProps; key: string }) => {
|
||||
link.url === undefined ? (
|
||||
<StyledAnchor href="#">{link.text}</StyledAnchor>
|
||||
) : (
|
||||
<StyledNavLink to={link.url} shouldOpenInNewTab={link.shouldOpenInNewTab}>
|
||||
{link.text}
|
||||
</StyledNavLink>
|
||||
<StyledNavLink to={link.url}>{link.text}</StyledNavLink>
|
||||
);
|
||||
return (
|
||||
<LinkWrap>
|
||||
|
||||
@@ -14,16 +14,19 @@ interface Props {
|
||||
description: string;
|
||||
figure?: React.ReactNode;
|
||||
actions?: React.ReactNode;
|
||||
background?: React.ReactNode;
|
||||
announcement?: AnnouncementProps;
|
||||
sectionPadding?: string;
|
||||
}
|
||||
|
||||
interface SectionProps {
|
||||
isAnnouncement?: boolean;
|
||||
padding?: string;
|
||||
}
|
||||
|
||||
const Section = styled.section<SectionProps>`
|
||||
padding: ${props => (props.isAnnouncement ? '50px 0 120px 0' : '120px 0')};
|
||||
|
||||
padding: ${props => props.padding || (props.isAnnouncement ? '50px 0 120px 0' : '120px 0')};
|
||||
position: relative;
|
||||
@media (max-width: 768px) {
|
||||
padding: 60px 0;
|
||||
}
|
||||
@@ -126,8 +129,18 @@ const ButtonWrap = styled.div`
|
||||
}
|
||||
`;
|
||||
|
||||
const BackgroundWrap = styled.div`
|
||||
position: absolute;
|
||||
overflow: hidden;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
`;
|
||||
|
||||
export const Hero: React.StatelessComponent<Props> = (props: Props) => (
|
||||
<Section isAnnouncement={!!props.announcement}>
|
||||
<Section padding={props.sectionPadding} isAnnouncement={!!props.announcement}>
|
||||
{!!props.background && <BackgroundWrap>{props.background}</BackgroundWrap>}
|
||||
<Wrap isCentered={!props.figure} isFullWidth={props.isFullWidth} isCenteredMobile={props.isCenteredMobile}>
|
||||
{props.figure && <Content width="400px">{props.figure}</Content>}
|
||||
|
||||
|
||||
@@ -74,7 +74,6 @@ export const Column = styled.div<ColumnProps>`
|
||||
export const FlexWrap = styled.div<FlexProps>`
|
||||
max-width: 1500px;
|
||||
margin: 0 auto;
|
||||
padding: ${props => props.padding};
|
||||
|
||||
@media (min-width: ${props => props.flexBreakpoint || '768px'}) {
|
||||
display: ${props => props.isFlex && 'flex'};
|
||||
@@ -93,7 +92,7 @@ const SectionBase = styled.section<SectionProps>`
|
||||
width: ${props => !props.isFullWidth && 'calc(100% - 60px)'};
|
||||
max-width: 1500px;
|
||||
margin: 0 auto;
|
||||
padding: ${props => props.isPadded && '120px 0'};
|
||||
padding: ${props => props.isPadded && (props.padding || '120px 0')};
|
||||
background-color: ${props => props.theme[`${props.bgColor}BgColor`] || props.bgColor};
|
||||
position: relative;
|
||||
overflow: ${props => !props.isFullWidth && 'hidden'};
|
||||
@@ -109,6 +108,9 @@ const Wrap = styled(FlexWrap)<WrapProps>`
|
||||
max-width: ${props => !props.isFullWidth && (props.maxWidth || '895px')};
|
||||
text-align: ${props => props.isTextCentered && 'center'};
|
||||
margin: 0 auto;
|
||||
@media (max-width: 768px) {
|
||||
width: ${props => (!!props.bgColor ? 'calc(100% - 60px)' : '100%')};
|
||||
}
|
||||
`;
|
||||
|
||||
export const WrapGrid = styled(Wrap)<WrapProps>`
|
||||
|
||||
91
packages/website/ts/components/showcase_section.tsx
Normal file
91
packages/website/ts/components/showcase_section.tsx
Normal file
@@ -0,0 +1,91 @@
|
||||
import * as React from 'react';
|
||||
import styled from 'styled-components';
|
||||
|
||||
interface Props {
|
||||
children?: React.ReactNode;
|
||||
showcaseImgSrc: string;
|
||||
maxWidth?: string;
|
||||
sectionPadding?: string;
|
||||
paddingMobile?: string;
|
||||
}
|
||||
|
||||
const ShowcaseSideImg = styled.img`
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
right: -10rem;
|
||||
margin: auto 0 auto 0;
|
||||
width: 60%;
|
||||
max-width: 800px;
|
||||
height: 100%;
|
||||
@media (max-width: 900px) {
|
||||
position: relative;
|
||||
right: 0;
|
||||
display: block;
|
||||
width: 100%;
|
||||
padding: 0 30px;
|
||||
}
|
||||
|
||||
@media (min-width: 1800px) {
|
||||
display: none;
|
||||
}
|
||||
`;
|
||||
|
||||
const ShowcaseImg = styled.img`
|
||||
display: none;
|
||||
@media (min-width: 1800px) {
|
||||
width: auto;
|
||||
max-height: 500px;
|
||||
display: block;
|
||||
}
|
||||
`;
|
||||
|
||||
interface SectionProps {
|
||||
sectionPadding?: string;
|
||||
paddingMobile?: string;
|
||||
}
|
||||
|
||||
const Section = styled.section<SectionProps>`
|
||||
position: relative;
|
||||
padding: ${props => props.sectionPadding || '0 0'};
|
||||
@media (max-width: 768px) {
|
||||
padding: ${props => props.paddingMobile || '40px 0'};
|
||||
}
|
||||
margin: 0 auto;
|
||||
`;
|
||||
|
||||
interface WrapProps {
|
||||
padding?: string;
|
||||
maxWidth?: string;
|
||||
}
|
||||
|
||||
const Wrap = styled.div<WrapProps>`
|
||||
display: flex;
|
||||
align-self: center;
|
||||
width: calc(100% - 60px);
|
||||
margin: 0 auto;
|
||||
padding: ${props => props.padding || '120px 0'};
|
||||
max-width: ${props => props.maxWidth || '100%'};
|
||||
@media (min-width: 1800px) {
|
||||
max-width: 1500px;
|
||||
}
|
||||
`;
|
||||
|
||||
const ContentWrap = styled.div`
|
||||
width: 50%;
|
||||
display: flex;
|
||||
align-self: center;
|
||||
@media (max-width: 900px) {
|
||||
width: 100%;
|
||||
}
|
||||
`;
|
||||
|
||||
export const ShowcaseSection = (props: Props) => (
|
||||
<Section paddingMobile={props.paddingMobile} sectionPadding={props.sectionPadding}>
|
||||
<ShowcaseSideImg src={props.showcaseImgSrc} />
|
||||
<Wrap maxWidth={props.maxWidth} padding={'80px 0'}>
|
||||
<ContentWrap>{props.children}</ContentWrap>
|
||||
<ShowcaseImg src={props.showcaseImgSrc} />
|
||||
</Wrap>
|
||||
</Section>
|
||||
);
|
||||
102
packages/website/ts/components/simple_definition.tsx
Normal file
102
packages/website/ts/components/simple_definition.tsx
Normal file
@@ -0,0 +1,102 @@
|
||||
import * as React from 'react';
|
||||
import styled from 'styled-components';
|
||||
|
||||
import { Button } from 'ts/components/button';
|
||||
import { Heading, Paragraph } from 'ts/components/text';
|
||||
|
||||
export interface Action {
|
||||
label: string;
|
||||
url?: string;
|
||||
onClick?: () => void;
|
||||
shouldUseAnchorTag?: boolean;
|
||||
}
|
||||
|
||||
interface Props {
|
||||
isInline?: boolean;
|
||||
isCentered?: boolean;
|
||||
isWithMargin?: boolean;
|
||||
fontSize?: 'default' | 'medium' | number;
|
||||
title: string;
|
||||
titleSize?: 'small' | 'default' | number;
|
||||
description: React.ReactNode | string;
|
||||
actions?: Action[];
|
||||
}
|
||||
|
||||
export const SimpleDefinition = (props: Props) => (
|
||||
<Wrap {...props}>
|
||||
<Heading
|
||||
asElement="h2"
|
||||
fontWeight="400"
|
||||
marginBottom={props.titleSize === 'small' ? '7px' : '15px'}
|
||||
size={props.titleSize || 'default'}
|
||||
>
|
||||
{props.title}
|
||||
</Heading>
|
||||
|
||||
{typeof props.description === 'string' ? (
|
||||
<Paragraph isMuted={true} size={props.fontSize || 'default'}>
|
||||
{props.description}
|
||||
</Paragraph>
|
||||
) : (
|
||||
<>{props.description}</>
|
||||
)}
|
||||
|
||||
{props.actions && (
|
||||
<LinkWrap>
|
||||
{props.actions.map((item, index) => (
|
||||
<Button
|
||||
key={`dlink-${index}`}
|
||||
href={item.url}
|
||||
onClick={item.onClick}
|
||||
isWithArrow={true}
|
||||
isAccentColor={true}
|
||||
shouldUseAnchorTag={item.shouldUseAnchorTag}
|
||||
target="_blank"
|
||||
>
|
||||
{item.label}
|
||||
</Button>
|
||||
))}
|
||||
</LinkWrap>
|
||||
)}
|
||||
</Wrap>
|
||||
);
|
||||
|
||||
const Wrap = styled.div<Props>`
|
||||
width: 100%;
|
||||
max-width: 560px;
|
||||
|
||||
ul {
|
||||
padding-top: 10px;
|
||||
padding-left: 1rem;
|
||||
}
|
||||
|
||||
li {
|
||||
color: ${props => props.theme.paragraphColor};
|
||||
font-size: ${props => `var(--${props.fontSize || 'default'}Paragraph)`};
|
||||
font-weight: 300;
|
||||
list-style: disc;
|
||||
opacity: 0.75;
|
||||
line-height: 1.444444444;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
`;
|
||||
|
||||
const LinkWrap = styled.div`
|
||||
margin-top: 60px;
|
||||
|
||||
@media (min-width: 768px) {
|
||||
display: inline-flex;
|
||||
|
||||
a + a {
|
||||
margin-left: 60px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
max-width: 250px;
|
||||
|
||||
a + a {
|
||||
margin-top: 15px;
|
||||
}
|
||||
}
|
||||
`;
|
||||
@@ -1,4 +1,7 @@
|
||||
<svg width="91" height="90" viewBox="0 0 91 90" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M2 45C2 68.7579 21.2421 88 45 88C68.7579 88 88 68.7579 88 45C88 21.6448 69.3906 2.63278 46.1793 2.02876C45.7478 2.02876 45.3452 2 44.9137 2C21.2134 2.02876 2 21.2709 2 45Z" stroke="#00AE99" stroke-width="3" stroke-miterlimit="10" stroke-linejoin="round"/>
|
||||
<path d="M67.7548 20.2253V59.6647C67.7548 65.8083 62.7745 70.7886 56.6309 70.7886V70.7886C50.4873 70.7886 45.507 65.8083 45.507 59.6647V31.3492C45.507 25.2057 40.5266 20.2253 34.383 20.2253V20.2253C28.2395 20.2253 23.2591 25.2057 23.2591 31.3492V70.7886M67.7548 20.2253L60.676 27.3042M67.7548 20.2253L74.8337 27.3042M23.2591 70.7886L15.6746 63.2041M23.2591 70.7886L30.8436 63.2041" stroke="#00AE99" stroke-width="3"/>
|
||||
<svg width="80" height="79" viewBox="0 0 80 79" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M1.77783 39.2222C1.77783 60.3403 18.882 77.4444 40 77.4444C61.1181 77.4444 78.2223 60.3403 78.2223 39.2222C78.2223 18.4621 61.6806 1.56247 41.0483 1.02557C40.6648 1.02557 40.3069 1 39.9234 1C18.8564 1.02557 1.77783 18.1297 1.77783 39.2222Z" stroke="#00AE99" stroke-width="2" stroke-miterlimit="10" stroke-linejoin="round"/>
|
||||
<path d="M60.2261 17.1997V52.2569C60.2261 57.7179 55.7991 62.1449 50.3381 62.1449V62.1449C44.8772 62.1449 40.4502 57.7179 40.4502 52.2569V27.0876C40.4502 21.6267 36.0232 17.1997 30.5623 17.1997V17.1997C25.1013 17.1997 20.6743 21.6267 20.6743 27.0876V62.1449" stroke="#00AE99" stroke-width="2" stroke-linecap="round"/>
|
||||
<path d="M2 39.2222C2 60.3403 19.1041 77.4444 40.2222 77.4444C61.3403 77.4444 78.4444 60.3403 78.4444 39.2222C78.4444 18.4621 61.9028 1.56247 41.2704 1.02557C40.8869 1.02557 40.529 1 40.1455 1C19.0786 1.02557 2 18.1297 2 39.2222Z" stroke="#00AE99" stroke-width="2" stroke-miterlimit="10" stroke-linejoin="round"/>
|
||||
<path d="M53.8999 23.492L60.1922 17.1997L66.4846 23.492" stroke="#00AE99" stroke-width="2"/>
|
||||
<path d="M13.8999 55.4031L20.6417 62.1449L27.3835 55.4031" stroke="#00AE99" stroke-width="2"/>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 786 B After Width: | Height: | Size: 1.2 KiB |
6
packages/website/ts/icons/illustrations/secure.svg
generated
Normal file
6
packages/website/ts/icons/illustrations/secure.svg
generated
Normal file
@@ -0,0 +1,6 @@
|
||||
<svg width="82" height="82" viewBox="0 0 82 82" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M1 41C1 63.1003 18.8997 81 41 81C63.1003 81 81 63.1003 81 41C81 19.2743 63.689 1.58863 42.097 1.02676C41.6956 1.02676 41.3211 1 40.9197 1C18.8729 1.02676 1 18.9264 1 41Z" stroke="#00AE99" stroke-width="2" stroke-miterlimit="10" stroke-linejoin="round"/>
|
||||
<path d="M19.1396 32.1628H61.9303V59.9057L40.535 68.4419L19.1396 59.9057V32.1628Z" stroke="#00AE99" stroke-width="2" stroke-miterlimit="10" stroke-linejoin="round"/>
|
||||
<path d="M26.5815 26.5814C26.5815 18.8751 32.8287 12.6279 40.535 12.6279V12.6279C48.2413 12.6279 54.4885 18.8751 54.4885 26.5814V32.1628H26.5815V26.5814Z" stroke="#00AE99" stroke-width="2" stroke-miterlimit="10" stroke-linejoin="round"/>
|
||||
<rect x="37.7441" y="42.3953" width="5.5814" height="13.0233" rx="2.7907" stroke="#00AE99" stroke-width="2" stroke-miterlimit="10" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 927 B |
@@ -140,7 +140,7 @@ export class Next0xInstant extends React.Component<Props> {
|
||||
/>
|
||||
<ModalContact isOpen={this.state.isContactModalOpen} onDismiss={this._onDismissContactModal} />
|
||||
|
||||
<Section maxWidth="1170px" isPadded={false} padding="60px 0">
|
||||
<Section maxWidth="1170px" isPadded={true} padding="60px 0">
|
||||
<Paragraph size="small" isMuted={0.5}>
|
||||
Disclaimer: The laws and regulations applicable to the use and exchange of digital assets and
|
||||
blockchain-native tokens, including through any software developed using the licensed work
|
||||
|
||||
@@ -2,29 +2,70 @@ import * as _ from 'lodash';
|
||||
import * as React from 'react';
|
||||
import { Banner } from 'ts/components/banner';
|
||||
import { Button } from 'ts/components/button';
|
||||
import { CheckedLi, CheckedUl } from 'ts/components/checkmark_list';
|
||||
import { Definition } from 'ts/components/definition';
|
||||
import { DocumentTitle } from 'ts/components/document_title';
|
||||
import { Hero } from 'ts/components/hero';
|
||||
import { Icon } from 'ts/components/icon';
|
||||
import { Section } from 'ts/components/newLayout';
|
||||
import { ShowcaseSection } from 'ts/components/showcase_section';
|
||||
import { SimpleDefinition } from 'ts/components/simple_definition';
|
||||
import { SiteWrap } from 'ts/components/siteWrap';
|
||||
import { Heading, Paragraph } from 'ts/components/text';
|
||||
import { constants } from 'ts/utils/constants';
|
||||
import { documentConstants } from 'ts/utils/document_meta_constants';
|
||||
|
||||
import { BackgroundMarquee } from '../components/background_marquee';
|
||||
import { ModalContact } from '../components/modals/modal_contact';
|
||||
|
||||
const offersData = [
|
||||
{
|
||||
icon: 'supportForAllEthereumStandards',
|
||||
title: 'Perfect for developers who need a simple drop-in marketplace',
|
||||
description: (
|
||||
<ul>
|
||||
<li>Quickly launch a market for your project’s token</li>
|
||||
<li>Seamlessly create an in-game marketplace for digital items and collectables</li>
|
||||
<li>Easily build a 0x relayer for your local market</li>
|
||||
</ul>
|
||||
),
|
||||
title: 'Accelerate Your Development',
|
||||
description:
|
||||
'Let Launch Kit take care of the complexities of building a relayer. The codebase allows you to connect to wallets, wrap ETH, make and take orders, and get notified of order state changes so you can spend more time on making your relayer your own.',
|
||||
showcaseUrl: 'images/launch_kit/relayer_screenshot.png',
|
||||
links: [
|
||||
{
|
||||
label: 'Get Started',
|
||||
url: `${constants.URL_LAUNCH_KIT}`,
|
||||
},
|
||||
{
|
||||
label: 'Live Demo',
|
||||
url: `${constants.URL_LAUNCH_KIT_ERC20_DEMO}`,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'Create a Market for Your Tokens',
|
||||
description:
|
||||
'Launch Kit supports all ERC-20 and ERC-721 tokens out of the box. Trade commodities with the ERC-20 exchange interface, or bid on crypto collectibles with the ERC-721 marketplace interface.',
|
||||
showcaseUrl: 'images/launch_kit/NFT_screenshot.png',
|
||||
links: [
|
||||
{
|
||||
label: 'Get Started',
|
||||
url: `${constants.URL_LAUNCH_KIT}`,
|
||||
},
|
||||
{
|
||||
label: 'Live Demo',
|
||||
url: `${constants.URL_LAUNCH_KIT_ERC721_DEMO}`,
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
const featuresList = [
|
||||
[
|
||||
'React UI for ERC-20 & ERC-721 tokens',
|
||||
'Market & Limit Orders',
|
||||
'Automatic Order Validation',
|
||||
'Order Status Notifications',
|
||||
'Dutch Auctions for ERC-721 tokens',
|
||||
],
|
||||
[
|
||||
'Docker Image for One-Click Deploy',
|
||||
'Standard Relayer API for Sharing Orders',
|
||||
'Wrapped ETH Abstraction for Easy Market Buys',
|
||||
'Support for all Web3 Wallets',
|
||||
],
|
||||
];
|
||||
|
||||
export class NextLaunchKit extends React.Component {
|
||||
@@ -33,70 +74,99 @@ export class NextLaunchKit extends React.Component {
|
||||
};
|
||||
public render(): React.ReactNode {
|
||||
return (
|
||||
<SiteWrap theme="dark">
|
||||
<SiteWrap>
|
||||
<DocumentTitle {...documentConstants.LAUNCH_KIT} />
|
||||
<Hero
|
||||
isLargeTitle={false}
|
||||
isFullWidth={false}
|
||||
isLargeTitle={true}
|
||||
isFullWidth={true}
|
||||
title="0x Launch Kit"
|
||||
description="Launch a relayer in under a minute"
|
||||
figure={<Icon name="launchKit" size="hero" margin={['small', 0, 'small', 0]} />}
|
||||
description="Launch your own exchange or marketplace in minutes"
|
||||
background={<BackgroundMarquee imgSrcUrl="images/launch_kit/background_marquee.png" />}
|
||||
actions={<HeroActions />}
|
||||
sectionPadding={'120px 0 180px 0'}
|
||||
/>
|
||||
|
||||
<Section bgColor="dark" isFlex={true} maxWidth="1170px">
|
||||
<Definition
|
||||
title="Networked Liquidity Pool"
|
||||
title="Fully Featured, Out of the Box"
|
||||
titleSize="small"
|
||||
description="Tap into and share liquidity with other relayers"
|
||||
icon="networkedLiquidity"
|
||||
iconSize="medium"
|
||||
isInline={true}
|
||||
/>
|
||||
|
||||
<Definition
|
||||
title="Extensible Code Repo"
|
||||
titleSize="small"
|
||||
description="Fork and extend to support modes of exchange"
|
||||
description="Apply your branding to professionally built UI components to make it your own."
|
||||
icon="code-repo"
|
||||
iconSize="medium"
|
||||
isInline={true}
|
||||
/>
|
||||
|
||||
<Definition
|
||||
title="Exchange Ethereum based Tokens"
|
||||
title="Secure and 100% Open Source"
|
||||
titleSize="small"
|
||||
description="Enable trading for any ERC-20 or ERC-721 asset"
|
||||
icon="eth-based-tokens"
|
||||
description="Independently audited by ConsenSys Diligence, time-tested, and proven."
|
||||
icon="secure"
|
||||
iconSize="medium"
|
||||
isInline={true}
|
||||
/>
|
||||
|
||||
<Definition
|
||||
title="Flexible to Fit Your Needs"
|
||||
titleSize="small"
|
||||
description="Support for ERC-20 tokens, ERC-721 NFTs, auctions, custom assets, and more."
|
||||
icon="flexibleOrders"
|
||||
iconSize="medium"
|
||||
isInline={true}
|
||||
/>
|
||||
</Section>
|
||||
|
||||
<Section>
|
||||
{_.map(offersData, (item, index) => (
|
||||
<Definition
|
||||
{_.map(offersData, (item, index) => (
|
||||
<ShowcaseSection
|
||||
maxWidth="1170px"
|
||||
showcaseImgSrc={item.showcaseUrl}
|
||||
paddingMobile={index === 0 ? '80px 0 40 0' : '40px 0'}
|
||||
sectionPadding={index === 0 ? '160px 0 80px 0' : '80px 0'}
|
||||
>
|
||||
<SimpleDefinition
|
||||
key={`offers-${index}`}
|
||||
icon={item.icon}
|
||||
title={item.title}
|
||||
description={item.description}
|
||||
isInlineIcon={true}
|
||||
iconSize={240}
|
||||
actions={item.links}
|
||||
/>
|
||||
</ShowcaseSection>
|
||||
))}
|
||||
|
||||
<Section maxWidth="1170px" isFlex={true}>
|
||||
<Heading size={42}>Features</Heading>
|
||||
{_.map(featuresList, (details: string[], listIndex: number) => (
|
||||
<CheckedUl key={`features-list-${listIndex}`}>
|
||||
{_.map(details, (detail: string, detailIndex: number) => (
|
||||
<CheckedLi>{detail}</CheckedLi>
|
||||
))}
|
||||
</CheckedUl>
|
||||
))}
|
||||
</Section>
|
||||
|
||||
<Banner
|
||||
heading="Need more flexibility?"
|
||||
subline="Dive into our docs, or contact us if needed"
|
||||
mainCta={{
|
||||
text: 'Get Started',
|
||||
href: `${constants.URL_LAUNCH_KIT_BACKEND}/#table-of-contents`,
|
||||
href: `${constants.URL_LAUNCH_KIT}`,
|
||||
shouldOpenInNewTab: true,
|
||||
}}
|
||||
secondaryCta={{ text: 'Get in Touch', onClick: this._onOpenContactModal.bind(this) }}
|
||||
/>
|
||||
<ModalContact isOpen={this.state.isContactModalOpen} onDismiss={this._onDismissContactModal} />
|
||||
|
||||
<Section maxWidth="1170px" isPadded={true} padding="60px 0">
|
||||
<Paragraph size="small" isMuted={0.5}>
|
||||
Disclaimer: The laws and regulations applicable to the use and exchange of digital assets and
|
||||
blockchain-native tokens, including through any software developed using the licensed work
|
||||
created by ZeroEx Intl. (the “Work”), vary by jurisdiction. As set forth in the Apache License,
|
||||
Version 2.0 applicable to the Work, developers are “solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work,” which includes responsibility for ensuring
|
||||
compliance with any such applicable laws and regulations.
|
||||
</Paragraph>
|
||||
<Paragraph size="small" isMuted={0.5}>
|
||||
See the Apache License, Version 2.0 for the specific language governing all applicable
|
||||
permissions and limitations.
|
||||
</Paragraph>
|
||||
</Section>
|
||||
</SiteWrap>
|
||||
);
|
||||
}
|
||||
@@ -112,12 +182,17 @@ export class NextLaunchKit extends React.Component {
|
||||
|
||||
const HeroActions = () => (
|
||||
<React.Fragment>
|
||||
<Button href={constants.URL_LAUNCH_KIT_BACKEND} isInline={true} target="_blank">
|
||||
<Button href={constants.URL_LAUNCH_KIT} isInline={true} target="_blank">
|
||||
Get Started
|
||||
</Button>
|
||||
|
||||
<Button href={constants.URL_LAUNCH_KIT_BLOG_POST} isTransparent={true} isInline={true} target="_blank">
|
||||
Learn More!
|
||||
<Button
|
||||
href={constants.URL_LAUNCH_KIT_ERC20_DEMO}
|
||||
transparentBgColor={'#000000'}
|
||||
isTransparent={true}
|
||||
isInline={true}
|
||||
target="_blank"
|
||||
>
|
||||
Live Demo
|
||||
</Button>
|
||||
</React.Fragment>
|
||||
);
|
||||
|
||||
@@ -104,8 +104,9 @@ export const constants = {
|
||||
URL_WETH_IO: 'https://weth.io/',
|
||||
URL_CANONICAL_WETH_POST: 'https://blog.0xproject.com/canonical-weth-a9aa7d0279dd',
|
||||
URL_ZEROEX_CHAT,
|
||||
URL_LAUNCH_KIT_BACKEND: 'https://github.com/0xProject/0x-launch-kit-backend',
|
||||
URL_LAUNCH_KIT_BLOG_POST: 'https://blog.0xproject.com/introducing-the-0x-launch-kit-4acdc3453585',
|
||||
URL_LAUNCH_KIT: 'https://github.com/0xProject/0x-launch-kit',
|
||||
URL_LAUNCH_KIT_ERC20_DEMO: 'https://demo.0x.org/erc20/',
|
||||
URL_LAUNCH_KIT_ERC721_DEMO: 'https://demo.0x.org/marketplace/',
|
||||
URL_WEB3_DOCS: 'https://github.com/ethereum/wiki/wiki/JavaScript-API',
|
||||
URL_WEB3_DECODED_LOG_ENTRY_EVENT:
|
||||
'https://github.com/0xProject/web3-typescript-typings/blob/f5bcb96/index.d.ts#L123',
|
||||
|
||||
@@ -28,8 +28,9 @@ export const documentConstants: { [s: string]: DocumentMetadata } = {
|
||||
keywords: '',
|
||||
},
|
||||
LAUNCH_KIT: {
|
||||
title: '0x Launch Kit: Launch a relayer in under a minute',
|
||||
description: 'Launch Kit includes a set of tools and documentation to build a relayer on 0x.',
|
||||
title: '0x Launch Kit: Launch your own exchange or marketplace in minutes',
|
||||
description:
|
||||
'Launch Kit includes a set of tools, UI and documentation to build an exchange or marketplace in minutes on 0x.',
|
||||
keywords: '',
|
||||
},
|
||||
ABOUT: {
|
||||
|
||||
@@ -65,7 +65,7 @@ class NetworkId(Enum):
|
||||
|
||||
|
||||
NETWORK_TO_ADDRESSES: Dict[NetworkId, ContractAddresses] = {
|
||||
NetworkId.MAINNET: ContractAddresses(
|
||||
NetworkId.MAINNET: ContractAddresses( # nosec
|
||||
erc20_proxy="0x2240dab907db71e64d3e0dba4800c83b5c502d4e",
|
||||
erc721_proxy="0x208e41fb445f1bb1b6780d58356e81405f3e6127",
|
||||
zrx_token="0xe41d2489571d322189246dafa5ebde1f4699f498",
|
||||
@@ -77,7 +77,7 @@ NETWORK_TO_ADDRESSES: Dict[NetworkId, ContractAddresses] = {
|
||||
coordinator_registry="0x45797531b873fd5e519477a070a955764c1a5b07",
|
||||
coordinator="0x25aae5b981ce6683cc5aeea1855d927e0b59066f",
|
||||
),
|
||||
NetworkId.ROPSTEN: ContractAddresses(
|
||||
NetworkId.ROPSTEN: ContractAddresses( # nosec
|
||||
erc20_proxy="0xb1408f4c245a23c31b98d2c626777d4c0d766caa",
|
||||
erc721_proxy="0xe654aac058bfbf9f83fcaee7793311dd82f6ddb4",
|
||||
zrx_token="0xff67881f8d12f372d91baae9752eb3631ff0ed00",
|
||||
@@ -89,7 +89,7 @@ NETWORK_TO_ADDRESSES: Dict[NetworkId, ContractAddresses] = {
|
||||
coordinator_registry="0x403cc23e88c17c4652fb904784d1af640a6722d9",
|
||||
coordinator="0x25aae5b981ce6683cc5aeea1855d927e0b59066f",
|
||||
),
|
||||
NetworkId.RINKEBY: ContractAddresses(
|
||||
NetworkId.RINKEBY: ContractAddresses( # nosec
|
||||
exchange="0xbce0b5f6eb618c565c3e5f5cd69652bbc279f44e",
|
||||
erc20_proxy="0x2f5ae4f6106e89b4147651688a92256885c5f410",
|
||||
erc721_proxy="0x7656d773e11ff7383a14dcf09a9c50990481cd10",
|
||||
@@ -101,7 +101,7 @@ NETWORK_TO_ADDRESSES: Dict[NetworkId, ContractAddresses] = {
|
||||
coordinator_registry="0x1084b6a398e47907bae43fec3ff4b677db6e4fee",
|
||||
coordinator="0x25aae5b981ce6683cc5aeea1855d927e0b59066f",
|
||||
),
|
||||
NetworkId.KOVAN: ContractAddresses(
|
||||
NetworkId.KOVAN: ContractAddresses( # nosec
|
||||
erc20_proxy="0xf1ec01d6236d3cd881a0bf0130ea25fe4234003e",
|
||||
erc721_proxy="0x2a9127c745688a165106c11cd4d647d2220af821",
|
||||
zrx_token="0x2002d3812f58e35f0ea1ffbf80a75a38c32175fa",
|
||||
@@ -113,7 +113,7 @@ NETWORK_TO_ADDRESSES: Dict[NetworkId, ContractAddresses] = {
|
||||
coordinator_registry="0x09fb99968c016a3ff537bf58fb3d9fe55a7975d5",
|
||||
coordinator="0x25aae5b981ce6683cc5aeea1855d927e0b59066f",
|
||||
),
|
||||
NetworkId.GANACHE: ContractAddresses(
|
||||
NetworkId.GANACHE: ContractAddresses( # nosec
|
||||
exchange="0x48bacb9266a570d521063ef5dd96e61686dbe788",
|
||||
erc20_proxy="0x1dc4c1cefef38a777b15aa20260a54e584b16c48",
|
||||
erc721_proxy="0x1d7022f5b17d2f8b695918fb48fa1089c9f85401",
|
||||
|
||||
@@ -79,7 +79,7 @@ class StartTestRelayerCommand(distutils.command.build_py.build_py):
|
||||
|
||||
|
||||
class StopTestRelayerCommand(distutils.command.build_py.build_py):
|
||||
"""Custom command to tear down the local 0x-launch-kit-backend test relayer."""
|
||||
"""Custom command to tear down the 0x-launch-kit-backend test relayer."""
|
||||
|
||||
description = "Tear down launch-kit daemon."
|
||||
|
||||
|
||||
Reference in New Issue
Block a user