Created a reusable newsletter signup form and widget
This commit is contained in:
committed by
fabioberger
parent
7bad1d2921
commit
d56fb374a7
@@ -1,82 +0,0 @@
|
||||
import React from 'react';
|
||||
import styled from 'styled-components';
|
||||
|
||||
import { Heading, Paragraph } from 'ts/components/text';
|
||||
import { colors } from 'ts/style/colors';
|
||||
|
||||
export interface INewsletterSignupProps {
|
||||
heading?: string;
|
||||
description?: string;
|
||||
url?: string;
|
||||
}
|
||||
|
||||
export const NewsletterSignup: React.FC<INewsletterSignupProps> = props => {
|
||||
// @TODO: Add newsletter signup loading / success / error states
|
||||
return (
|
||||
<NewsletterSignupWrapper href={props.url}>
|
||||
<Heading marginBottom="8px">{props.heading}</Heading>
|
||||
<Paragraph marginBottom="25px">{props.description}</Paragraph>
|
||||
<InputWrapper>
|
||||
<Label htmlFor="emailSignup">Email Address</Label>
|
||||
<Input id="emailSignup" type="email" placeholder="Email Address" />
|
||||
<Submit>
|
||||
<svg width="22" height="17" viewBox="0 0 22 17" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
opacity=".5"
|
||||
d="M13.066 0l-1.068 1.147 6.232 6.557H0v1.592h18.23l-6.232 6.557L13.066 17l8.08-8.5-8.08-8.5z"
|
||||
fill="#5C5C5C"
|
||||
/>
|
||||
</svg>
|
||||
</Submit>
|
||||
</InputWrapper>
|
||||
</NewsletterSignupWrapper>
|
||||
);
|
||||
};
|
||||
|
||||
NewsletterSignup.defaultProps = {
|
||||
heading: 'Sign up for the Newsletter',
|
||||
description: 'Body font about the newseletter',
|
||||
};
|
||||
|
||||
const NewsletterSignupWrapper = styled.a`
|
||||
background-color: ${colors.backgroundLight};
|
||||
padding: 40px 30px 50px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
text-align: center;
|
||||
margin-bottom: 1.875rem;
|
||||
`;
|
||||
|
||||
const Label = styled.label`
|
||||
visibility: hidden;
|
||||
opacity: 0;
|
||||
position: absolute;
|
||||
width: 0;
|
||||
`;
|
||||
|
||||
const InputWrapper = styled.div`
|
||||
padding: 0 40px;
|
||||
position: relative;
|
||||
`;
|
||||
|
||||
const Input = styled.input`
|
||||
background-color: transparent;
|
||||
border: 0;
|
||||
border-bottom: 1px solid #cfcfcf;
|
||||
font-size: 1.1rem;
|
||||
font-weight: 300;
|
||||
width: 100%;
|
||||
outline: none;
|
||||
`;
|
||||
|
||||
const Submit = styled.button`
|
||||
background-color: transparent;
|
||||
border: 0;
|
||||
cursor: pointer;
|
||||
appearance: none;
|
||||
position: absolute;
|
||||
height: 100%;
|
||||
width: 50px;
|
||||
right: 40px;
|
||||
`;
|
||||
38
packages/website/ts/components/docs/newsletter_widget.tsx
Normal file
38
packages/website/ts/components/docs/newsletter_widget.tsx
Normal file
@@ -0,0 +1,38 @@
|
||||
import React from 'react';
|
||||
import styled from 'styled-components';
|
||||
|
||||
import { NewsletterForm } from 'ts/components/newsletter_form';
|
||||
import { Heading, Paragraph } from 'ts/components/text';
|
||||
|
||||
import { colors } from 'ts/style/colors';
|
||||
|
||||
export interface INewsletterWidgetProps {
|
||||
heading?: string;
|
||||
description?: string;
|
||||
url?: string;
|
||||
}
|
||||
|
||||
export const NewsletterWidget: React.FC<INewsletterWidgetProps> = props => {
|
||||
return (
|
||||
<NewsletterSignupWrapper href={props.url}>
|
||||
<Heading marginBottom="8px">{props.heading}</Heading>
|
||||
<Paragraph marginBottom="25px">{props.description}</Paragraph>
|
||||
<NewsletterForm color="#b1b1b1" />
|
||||
</NewsletterSignupWrapper>
|
||||
);
|
||||
};
|
||||
|
||||
NewsletterWidget.defaultProps = {
|
||||
heading: 'Sign up for the Newsletter',
|
||||
description: 'Body font about the newseletter',
|
||||
};
|
||||
|
||||
const NewsletterSignupWrapper = styled.a`
|
||||
background-color: ${colors.backgroundLight};
|
||||
padding: 40px 120px 50px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
text-align: center;
|
||||
margin-bottom: 1.875rem;
|
||||
`;
|
||||
@@ -76,6 +76,7 @@ export const Footer: React.StatelessComponent = () => (
|
||||
<FooterColumn width="35%">
|
||||
<Logo />
|
||||
<NewsletterForm />
|
||||
<Text>Subscribe to our newsletter for updates in the 0x ecosystem</Text>
|
||||
</FooterColumn>
|
||||
|
||||
<FooterColumn width="55%">
|
||||
@@ -170,3 +171,11 @@ const Link = styled(SmartLink)`
|
||||
opacity: 0.8;
|
||||
}
|
||||
`;
|
||||
|
||||
const Text = styled.p`
|
||||
color: #656565;
|
||||
font-size: 0.833333333rem;
|
||||
font-weight: 300;
|
||||
line-height: 1.2em;
|
||||
margin-top: 15px;
|
||||
`;
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
import React, { useState } from 'react';
|
||||
import styled, { withTheme } from 'styled-components';
|
||||
import styled, { keyframes } from 'styled-components';
|
||||
|
||||
import { ThemeValuesInterface } from 'ts/components/siteWrap';
|
||||
import { colors } from 'ts/style/colors';
|
||||
import { errorReporter } from 'ts/utils/error_reporter';
|
||||
import { utils } from 'ts/utils/utils';
|
||||
|
||||
interface IFormProps {
|
||||
theme: ThemeValuesInterface;
|
||||
color?: string;
|
||||
}
|
||||
|
||||
interface IInputProps {
|
||||
@@ -15,7 +13,7 @@ interface IInputProps {
|
||||
name: string;
|
||||
type: string;
|
||||
label: string;
|
||||
textColor: string;
|
||||
color?: string;
|
||||
required?: boolean;
|
||||
}
|
||||
|
||||
@@ -23,21 +21,7 @@ interface IArrowProps {
|
||||
isSubmitted: boolean;
|
||||
}
|
||||
|
||||
const Input = React.forwardRef((props: IInputProps, ref: React.Ref<HTMLInputElement>) => {
|
||||
const { name, label, type } = props;
|
||||
const id = `input-${name}`;
|
||||
|
||||
return (
|
||||
<InnerInputWrapper {...props}>
|
||||
<label className="visuallyHidden" htmlFor={id}>
|
||||
{label}
|
||||
</label>
|
||||
<StyledInput ref={ref} id={id} placeholder={label} type={type || 'text'} {...props} />
|
||||
</InnerInputWrapper>
|
||||
);
|
||||
});
|
||||
|
||||
const Form: React.FC<IFormProps> = ({ theme }) => {
|
||||
export const NewsletterForm: React.FC<IFormProps> = ({ color }) => {
|
||||
const [isSubmitted, setIsSubmitted] = useState<boolean>(false);
|
||||
const emailInput = React.createRef<HTMLInputElement>();
|
||||
|
||||
@@ -69,113 +53,100 @@ const Form: React.FC<IFormProps> = ({ theme }) => {
|
||||
|
||||
return (
|
||||
<StyledForm onSubmit={handleSubmit}>
|
||||
<InputWrapper>
|
||||
{isSubmitted ? (
|
||||
<SuccessText isSubmitted={isSubmitted}>🎉 Thank you for signing up!</SuccessText>
|
||||
) : (
|
||||
<Input
|
||||
color={color}
|
||||
isSubmitted={isSubmitted}
|
||||
name="email"
|
||||
type="email"
|
||||
label="Email Address"
|
||||
ref={emailInput}
|
||||
required={true}
|
||||
textColor={theme.textColor}
|
||||
/>
|
||||
)}
|
||||
|
||||
<SubmitButton>
|
||||
<Arrow
|
||||
isSubmitted={isSubmitted}
|
||||
width="22"
|
||||
height="17"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M13.066 0l-1.068 1.147 6.232 6.557H0v1.592h18.23l-6.232 6.557L13.066 17l8.08-8.5-8.08-8.5z"
|
||||
fill="#CBCBCB"
|
||||
/>
|
||||
</Arrow>
|
||||
</SubmitButton>
|
||||
<SuccessText isSubmitted={isSubmitted}>🎉 Thank you for signing up!</SuccessText>
|
||||
</InputWrapper>
|
||||
<Text>Subscribe to our newsletter for updates in the 0x ecosystem</Text>
|
||||
<SubmitButton>
|
||||
<Arrow
|
||||
color={color}
|
||||
isSubmitted={isSubmitted}
|
||||
width="22"
|
||||
height="17"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path d="M13.066 0l-1.068 1.147 6.232 6.557H0v1.592h18.23l-6.232 6.557L13.066 17l8.08-8.5-8.08-8.5z" />
|
||||
</Arrow>
|
||||
</SubmitButton>
|
||||
</StyledForm>
|
||||
);
|
||||
};
|
||||
|
||||
export const NewsletterForm = withTheme(Form);
|
||||
const Input = React.forwardRef((props: IInputProps, ref: React.Ref<HTMLInputElement>) => {
|
||||
const { name, label, type } = props;
|
||||
const id = `input-${name}`;
|
||||
|
||||
return (
|
||||
<>
|
||||
<label className="visuallyHidden" htmlFor={id}>
|
||||
{label}
|
||||
</label>
|
||||
<StyledInput ref={ref} id={id} placeholder={label} type={type || 'text'} {...props} />
|
||||
</>
|
||||
);
|
||||
});
|
||||
|
||||
const INPUT_HEIGHT = '60px';
|
||||
|
||||
const StyledForm = styled.form`
|
||||
appearance: none;
|
||||
border: 0;
|
||||
color: ${colors.white};
|
||||
padding: 13px 0 14px;
|
||||
margin-top: 27px;
|
||||
position: relative;
|
||||
margin-top: 24px;
|
||||
`;
|
||||
|
||||
const StyledInput = styled.input<IInputProps>`
|
||||
appearance: none;
|
||||
background-color: transparent;
|
||||
border: 0;
|
||||
border-bottom: 1px solid #393939;
|
||||
color: ${props => props.textColor || '#fff'};
|
||||
font-size: 1.294117647rem;
|
||||
padding: 15px 0;
|
||||
border-bottom: 1px solid ${({ color }) => color || '#393939'};
|
||||
color: ${({ theme }) => theme.textColor};
|
||||
height: ${INPUT_HEIGHT};
|
||||
font-size: 1.3rem;
|
||||
outline: none;
|
||||
width: 100%;
|
||||
|
||||
&::placeholder {
|
||||
color: #b1b1b1; // #9D9D9D on light theme
|
||||
color: #b1b1b1;
|
||||
}
|
||||
`;
|
||||
|
||||
const InputWrapper = styled.div`
|
||||
position: relative;
|
||||
`;
|
||||
|
||||
const InnerInputWrapper = styled.div<IArrowProps>`
|
||||
opacity: ${props => props.isSubmitted && 0};
|
||||
visibility: ${props => props.isSubmitted && 'hidden'};
|
||||
transition: opacity 0.25s ease-in-out, visibility 0.25s ease-in-out;
|
||||
transition-delay: 0.3s;
|
||||
`;
|
||||
|
||||
const SubmitButton = styled.button`
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
height: ${INPUT_HEIGHT};
|
||||
background-color: transparent;
|
||||
border: 0;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: calc(50% - 22px);
|
||||
top: 0;
|
||||
overflow: hidden;
|
||||
outline: 0;
|
||||
`;
|
||||
|
||||
const Text = styled.p`
|
||||
color: #656565;
|
||||
font-size: 0.833333333rem;
|
||||
font-weight: 300;
|
||||
line-height: 1.2em;
|
||||
margin-top: 15px;
|
||||
// prettier-ignore
|
||||
const fadeIn = keyframes`
|
||||
from { opacity: 0; }
|
||||
to { opacity: 1; }
|
||||
`;
|
||||
|
||||
const SuccessText = styled.p<IArrowProps>`
|
||||
color: #b1b1b1;
|
||||
font-size: 1rem;
|
||||
font-weight: 300;
|
||||
line-height: 1.2em;
|
||||
padding-top: 25px;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
text-align: left;
|
||||
right: 50px;
|
||||
opacity: ${props => (props.isSubmitted ? 1 : 0)};
|
||||
visibility: ${props => (props.isSubmitted ? 'visible' : 'hidden')};
|
||||
transition: opacity 0.25s ease-in-out, visibility 0.25s ease-in-out;
|
||||
transition-delay: 0.55s;
|
||||
line-height: ${INPUT_HEIGHT};
|
||||
animation: ${fadeIn} 0.3s ease-in-out;
|
||||
`;
|
||||
|
||||
const Arrow = styled.svg<IArrowProps>`
|
||||
transform: ${props => props.isSubmitted && `translateX(44px)`};
|
||||
fill: ${({ color }) => color};
|
||||
transform: ${({ isSubmitted }) => isSubmitted && `translateX(44px)`};
|
||||
transition: transform 0.25s ease-in-out;
|
||||
`;
|
||||
|
||||
@@ -6,7 +6,7 @@ import { FeatureLink } from 'ts/components/docs/feature_link';
|
||||
import { HelpCallout } from 'ts/components/docs/help_callout';
|
||||
import { HelpfulCta } from 'ts/components/docs/helpful_cta';
|
||||
import { Hero } from 'ts/components/docs/hero';
|
||||
import { NewsletterSignup } from 'ts/components/docs/newsletter_signup';
|
||||
import { NewsletterWidget } from 'ts/components/docs/newsletter_widget';
|
||||
import { Note } from 'ts/components/docs/note';
|
||||
import { Notification } from 'ts/components/docs/notification';
|
||||
import { Resource } from 'ts/components/docs/resource/resource';
|
||||
@@ -195,7 +195,6 @@ export const DocsPageTemplate: React.FC = () => {
|
||||
</Heading>
|
||||
<StepLinks links={usefulLinks} />
|
||||
<HelpCallout />
|
||||
<NewsletterSignup />
|
||||
<HelpfulCta />
|
||||
<div>
|
||||
<Heading asElement="h2" size="default">
|
||||
@@ -237,6 +236,7 @@ export const DocsPageTemplate: React.FC = () => {
|
||||
url="#"
|
||||
/>
|
||||
</div>
|
||||
<NewsletterWidget />
|
||||
</article>
|
||||
</Columns>
|
||||
</Section>
|
||||
|
||||
Reference in New Issue
Block a user