Merge pull request #1630 from bakkenbaeck/website-updates
[WIP] Extensions page and tweaks to website
This commit is contained in:
@@ -6,7 +6,7 @@ import { Button } from 'ts/components/button';
|
||||
import { ChapterLink } from 'ts/components/chapter_link';
|
||||
import { Column, Section } from 'ts/components/newLayout';
|
||||
import { SiteWrap } from 'ts/components/siteWrap';
|
||||
import { Heading, Paragraph } from 'ts/components/text';
|
||||
import { Heading } from 'ts/components/text';
|
||||
|
||||
import { addFadeInAnimation } from 'ts/constants/animations';
|
||||
import { WebsitePaths } from 'ts/types';
|
||||
@@ -34,9 +34,7 @@ export const AboutPageLayout = (props: Props) => (
|
||||
<Column width="100%" maxWidth="680px">
|
||||
<AnimatedHeading size="medium">{props.title}</AnimatedHeading>
|
||||
|
||||
<AnimatedParagraph size="medium" marginBottom="60px" isMuted={0.65}>
|
||||
{props.description}
|
||||
</AnimatedParagraph>
|
||||
<AnimatedIntro>{props.description}</AnimatedIntro>
|
||||
|
||||
{props.linkLabel && (props.href || props.to) && (
|
||||
<AnimatedLink
|
||||
@@ -61,7 +59,7 @@ const AnimatedHeading = styled(Heading)`
|
||||
${addFadeInAnimation('0.5s')};
|
||||
`;
|
||||
|
||||
const AnimatedParagraph = styled(Paragraph)`
|
||||
const AnimatedIntro = styled.div`
|
||||
${addFadeInAnimation('0.5s', '0.15s')};
|
||||
`;
|
||||
|
||||
|
||||
@@ -31,11 +31,17 @@ interface BorderProps {
|
||||
export const Banner: React.StatelessComponent<Props> = (props: Props) => {
|
||||
const { heading, subline, mainCta, secondaryCta } = props;
|
||||
return (
|
||||
<CustomSection bgColor={colors.brandDark} isFlex={true} flexBreakpoint="900px" paddingMobile="120px 0">
|
||||
<CustomSection
|
||||
bgColor={colors.brandDark}
|
||||
isFlex={true}
|
||||
flexBreakpoint="900px"
|
||||
paddingMobile="120px 0"
|
||||
alignItems="center"
|
||||
>
|
||||
<Border />
|
||||
<Border isBottom={true} />
|
||||
|
||||
<Column>
|
||||
<Column maxWidth="455px">
|
||||
<CustomHeading>{heading}</CustomHeading>
|
||||
|
||||
{subline && (
|
||||
@@ -44,7 +50,7 @@ export const Banner: React.StatelessComponent<Props> = (props: Props) => {
|
||||
</Paragraph>
|
||||
)}
|
||||
</Column>
|
||||
<Column>
|
||||
<ColumnCta>
|
||||
<ButtonWrap>
|
||||
{mainCta && (
|
||||
<Button
|
||||
@@ -69,7 +75,7 @@ export const Banner: React.StatelessComponent<Props> = (props: Props) => {
|
||||
</Button>
|
||||
)}
|
||||
</ButtonWrap>
|
||||
</Column>
|
||||
</ColumnCta>
|
||||
</CustomSection>
|
||||
);
|
||||
};
|
||||
@@ -77,8 +83,12 @@ export const Banner: React.StatelessComponent<Props> = (props: Props) => {
|
||||
const CustomSection = styled(Section)`
|
||||
color: ${colors.white};
|
||||
margin-top: 30px;
|
||||
margin-top: 0;
|
||||
|
||||
@media (max-width: 900px) {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
text-align: center;
|
||||
|
||||
p {
|
||||
@@ -91,10 +101,17 @@ const CustomSection = styled(Section)`
|
||||
}
|
||||
`;
|
||||
|
||||
const ColumnCta = styled(Column)`
|
||||
flex-shrink: 0;
|
||||
`;
|
||||
|
||||
const CustomHeading = styled.h2`
|
||||
font-size: 34px;
|
||||
line-height: normal;
|
||||
font-weight: 400;
|
||||
margin-bottom: 10px @media (max-width: 768px) {
|
||||
margin-bottom: 10px;
|
||||
|
||||
@media (max-width: 768px) {
|
||||
font-size: 30px;
|
||||
}
|
||||
`;
|
||||
|
||||
@@ -5,8 +5,11 @@ import styled from 'styled-components';
|
||||
import { ThemeInterface } from 'ts/components/siteWrap';
|
||||
|
||||
import { colors } from 'ts/style/colors';
|
||||
import { withFilteredProps } from 'ts/utils/filter_props';
|
||||
|
||||
export interface ButtonInterface {
|
||||
isDisabled?: boolean;
|
||||
className?: string;
|
||||
bgColor?: string;
|
||||
borderColor?: string;
|
||||
color?: string;
|
||||
@@ -22,27 +25,29 @@ export interface ButtonInterface {
|
||||
type?: string;
|
||||
target?: string;
|
||||
to?: string;
|
||||
onClick?: (e: Event) => any;
|
||||
onClick?: (e: any) => any;
|
||||
theme?: ThemeInterface;
|
||||
shouldUseAnchorTag?: boolean;
|
||||
}
|
||||
|
||||
export const Button: React.StatelessComponent<ButtonInterface> = (props: ButtonInterface) => {
|
||||
const { children, href, isWithArrow, to, shouldUseAnchorTag, target } = props;
|
||||
const { children, href, isWithArrow, to, shouldUseAnchorTag, target, isDisabled, className } = props;
|
||||
const isButton = !href && !to;
|
||||
let linkElem;
|
||||
|
||||
if (href || shouldUseAnchorTag) {
|
||||
linkElem = 'a';
|
||||
}
|
||||
if (to) {
|
||||
linkElem = ReactRouterLink;
|
||||
linkElem = withFilteredProps(ReactRouterLink, ['className', 'href', 'to', 'onClick', 'target']);
|
||||
}
|
||||
|
||||
const Component = linkElem ? ButtonBase.withComponent<any>(linkElem) : ButtonBase;
|
||||
const targetProp = href && target ? { target } : {};
|
||||
const buttonProps = isButton ? { disabled: isDisabled } : {};
|
||||
|
||||
return (
|
||||
<Component {...props} {...targetProp}>
|
||||
<Component className={className} {...buttonProps} {...props} {...targetProp}>
|
||||
{children}
|
||||
|
||||
{isWithArrow && (
|
||||
|
||||
96
packages/website/ts/components/card.tsx
Normal file
96
packages/website/ts/components/card.tsx
Normal file
@@ -0,0 +1,96 @@
|
||||
import * as _ from 'lodash';
|
||||
import * as React from 'react';
|
||||
import styled from 'styled-components';
|
||||
|
||||
import { colors } from 'ts/style/colors';
|
||||
|
||||
import { Button } from 'ts/components/button';
|
||||
import { Icon } from 'ts/components/icon';
|
||||
import { Heading, Paragraph } from 'ts/components/text';
|
||||
|
||||
export interface LinkProps {
|
||||
text: string;
|
||||
url: string;
|
||||
}
|
||||
|
||||
interface CardProps {
|
||||
icon: string;
|
||||
heading: string;
|
||||
description: string;
|
||||
href?: string;
|
||||
links?: LinkProps[];
|
||||
}
|
||||
|
||||
export const Card: React.StatelessComponent<CardProps> = (props: CardProps) => {
|
||||
const { heading, description, icon, links } = props;
|
||||
|
||||
return (
|
||||
<StyledCard>
|
||||
<CardHead>
|
||||
<Icon name={icon} size={160} />
|
||||
</CardHead>
|
||||
<CardContent>
|
||||
<Heading asElement="h4" size="default" marginBottom="15px">
|
||||
{heading}
|
||||
</Heading>
|
||||
<Paragraph isMuted={true}>{description}</Paragraph>
|
||||
<Links>
|
||||
{_.map(links, (link, index) => (
|
||||
<Button
|
||||
href={link.url}
|
||||
target={!_.isUndefined(link.url) ? '_blank' : undefined}
|
||||
isWithArrow={true}
|
||||
isAccentColor={true}
|
||||
key={`cardLink-${index}-${link.url}`}
|
||||
>
|
||||
{link.text}
|
||||
</Button>
|
||||
))}
|
||||
</Links>
|
||||
</CardContent>
|
||||
</StyledCard>
|
||||
);
|
||||
};
|
||||
|
||||
const StyledCard = styled.div`
|
||||
background-color: ${colors.backgroundDark};
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
min-height: 520px;
|
||||
flex: 0 0 auto;
|
||||
transition: opacity 0.4s ease-in-out;
|
||||
|
||||
@media (max-width: 500px) {
|
||||
min-height: 450px;
|
||||
}
|
||||
`;
|
||||
|
||||
const CardHead = styled.div`
|
||||
background-color: ${colors.brandDark};
|
||||
height: 240px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 40px 0;
|
||||
|
||||
@media (max-width: 500px) {
|
||||
height: 180px;
|
||||
padding: 30px 0;
|
||||
}
|
||||
`;
|
||||
|
||||
const CardContent = styled.div`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 30px;
|
||||
flex-grow: 1;
|
||||
|
||||
@media (max-width: 500px) {
|
||||
padding: 20px;
|
||||
}
|
||||
`;
|
||||
|
||||
const Links = styled.div`
|
||||
margin-top: auto;
|
||||
`;
|
||||
@@ -17,6 +17,11 @@ const navData = [
|
||||
description: 'Build on the 0x protocol',
|
||||
url: WebsitePaths.LaunchKit,
|
||||
},
|
||||
{
|
||||
title: 'Extensions',
|
||||
description: 'Support new types of trading on your relayer with 0x Extensions',
|
||||
url: WebsitePaths.Extensions,
|
||||
},
|
||||
{
|
||||
title: 'Governance',
|
||||
description: 'Vote on changes to the 0x protocol',
|
||||
|
||||
@@ -33,6 +33,7 @@ const linkRows: LinkRows[] = [
|
||||
links: [
|
||||
{ url: WebsitePaths.Instant, text: '0x Instant' },
|
||||
{ url: WebsitePaths.LaunchKit, text: '0x Launch Kit' },
|
||||
{ url: WebsitePaths.Extensions, text: 'Extensions' },
|
||||
{ url: WebsitePaths.Vote, text: 'Governance' },
|
||||
],
|
||||
},
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -64,6 +64,8 @@ const StyledIcon = styled.figure<IconProps>`
|
||||
margin: ${props => getCSSPadding(props.margin)};
|
||||
display: inline-block;
|
||||
flex-shrink: 0;
|
||||
max-height: 100%;
|
||||
max-width: 100%;
|
||||
|
||||
svg {
|
||||
width: 100%;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import * as React from 'react';
|
||||
import styled from 'styled-components';
|
||||
import { withFilteredProps } from 'ts/utils/filter_props';
|
||||
|
||||
interface Props {
|
||||
alt?: string;
|
||||
@@ -12,6 +13,6 @@ const ImageClass: React.FunctionComponent<Props> = (props: Props) => {
|
||||
return <img {...props} />;
|
||||
};
|
||||
|
||||
export const Image = styled(ImageClass)<Props>`
|
||||
export const Image = styled(withFilteredProps(ImageClass, ['alt', 'src']))<Props>`
|
||||
margin: ${props => props.isCentered && `0 auto`};
|
||||
`;
|
||||
|
||||
@@ -32,12 +32,14 @@ export interface SectionProps extends WrapProps {
|
||||
maxWidth?: string;
|
||||
bgColor?: 'dark' | 'light' | string;
|
||||
children: any;
|
||||
alignItems?: string;
|
||||
}
|
||||
|
||||
export interface FlexProps {
|
||||
padding?: string;
|
||||
isFlex?: boolean;
|
||||
flexBreakpoint?: string;
|
||||
alignItems?: string;
|
||||
}
|
||||
|
||||
export interface ColumnProps {
|
||||
@@ -76,6 +78,7 @@ export const FlexWrap = styled.div<FlexProps>`
|
||||
@media (min-width: ${props => props.flexBreakpoint || '768px'}) {
|
||||
display: ${props => props.isFlex && 'flex'};
|
||||
justify-content: ${props => props.isFlex && 'space-between'};
|
||||
align-items: ${props => props.alignItems};
|
||||
}
|
||||
`;
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ import { GlobalStyles } from 'ts/constants/globalStyle';
|
||||
|
||||
interface Props {
|
||||
theme?: 'dark' | 'light' | 'gray';
|
||||
isFullScreen?: boolean;
|
||||
children: any;
|
||||
}
|
||||
|
||||
@@ -18,6 +19,7 @@ interface State {
|
||||
|
||||
interface MainProps {
|
||||
isNavToggled: boolean;
|
||||
isFullScreen?: boolean;
|
||||
}
|
||||
|
||||
export interface ThemeValuesInterface {
|
||||
@@ -118,7 +120,7 @@ export class SiteWrap extends React.Component<Props, State> {
|
||||
};
|
||||
|
||||
public render(): React.ReactNode {
|
||||
const { children, theme = 'dark' } = this.props;
|
||||
const { children, theme = 'dark', isFullScreen } = this.props;
|
||||
const { isMobileNavOpen } = this.state;
|
||||
const currentTheme = GLOBAL_THEMES[theme];
|
||||
|
||||
@@ -130,7 +132,9 @@ export class SiteWrap extends React.Component<Props, State> {
|
||||
|
||||
<Header isNavToggled={isMobileNavOpen} toggleMobileNav={this.toggleMobileNav} />
|
||||
|
||||
<Main isNavToggled={isMobileNavOpen}>{children}</Main>
|
||||
<Main isNavToggled={isMobileNavOpen} isFullScreen={isFullScreen}>
|
||||
{children}
|
||||
</Main>
|
||||
|
||||
<Footer />
|
||||
</>
|
||||
@@ -143,4 +147,12 @@ export class SiteWrap extends React.Component<Props, State> {
|
||||
const Main = styled.main<MainProps>`
|
||||
transition: transform 0.5s, opacity 0.5s;
|
||||
opacity: ${props => props.isNavToggled && '0.5'};
|
||||
|
||||
${props =>
|
||||
props.isFullScreen &&
|
||||
`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
min-height: calc(100vh - 108px - 381px);
|
||||
`}
|
||||
`;
|
||||
|
||||
Reference in New Issue
Block a user