Refactored newsletter form into a stateless component

This commit is contained in:
Piotr Janosz
2019-07-07 15:59:36 +02:00
committed by fabioberger
parent 37dd494abd
commit 7bad1d2921

View File

@@ -1,4 +1,4 @@
import React from 'react';
import React, { useState } from 'react';
import styled, { withTheme } from 'styled-components';
import { ThemeValuesInterface } from 'ts/components/siteWrap';
@@ -6,11 +6,11 @@ import { colors } from 'ts/style/colors';
import { errorReporter } from 'ts/utils/error_reporter';
import { utils } from 'ts/utils/utils';
interface FormProps {
interface IFormProps {
theme: ThemeValuesInterface;
}
interface InputProps {
interface IInputProps {
isSubmitted: boolean;
name: string;
type: string;
@@ -19,11 +19,11 @@ interface InputProps {
required?: boolean;
}
interface ArrowProps {
interface IArrowProps {
isSubmitted: boolean;
}
const Input = React.forwardRef((props: InputProps, ref: React.Ref<HTMLInputElement>) => {
const Input = React.forwardRef((props: IInputProps, ref: React.Ref<HTMLInputElement>) => {
const { name, label, type } = props;
const id = `input-${name}`;
@@ -37,56 +37,17 @@ const Input = React.forwardRef((props: InputProps, ref: React.Ref<HTMLInputEleme
);
});
class Form extends React.Component<FormProps> {
public emailInput = React.createRef<HTMLInputElement>();
public state = {
isSubmitted: false,
};
public render(): React.ReactNode {
const { isSubmitted } = this.state;
const { theme } = this.props;
const Form: React.FC<IFormProps> = ({ theme }) => {
const [isSubmitted, setIsSubmitted] = useState<boolean>(false);
const emailInput = React.createRef<HTMLInputElement>();
return (
<StyledForm onSubmit={this._onSubmitAsync.bind(this)}>
<InputWrapper>
<Input
isSubmitted={isSubmitted}
name="email"
type="email"
label="Email Address"
ref={this.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>
</StyledForm>
);
}
private async _onSubmitAsync(e: React.FormEvent<HTMLFormElement>): Promise<void> {
const handleSubmit = async (e: React.FormEvent<HTMLFormElement>): Promise<void> => {
e.preventDefault();
const email = this.emailInput.current.value;
const email = emailInput.current.value;
const referrer = 'https://0x.org/';
this.setState({ isSubmitted: true });
setIsSubmitted(true);
if (email === 'triggererror@0xproject.org') {
throw new Error('Manually triggered error');
@@ -104,8 +65,41 @@ class Form extends React.Component<FormProps> {
} catch (e) {
errorReporter.report(e);
}
}
}
};
return (
<StyledForm onSubmit={handleSubmit}>
<InputWrapper>
<Input
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>
</StyledForm>
);
};
export const NewsletterForm = withTheme(Form);
@@ -117,7 +111,7 @@ const StyledForm = styled.form`
margin-top: 27px;
`;
const StyledInput = styled.input<InputProps>`
const StyledInput = styled.input<IInputProps>`
appearance: none;
background-color: transparent;
border: 0;
@@ -137,7 +131,7 @@ const InputWrapper = styled.div`
position: relative;
`;
const InnerInputWrapper = styled.div<ArrowProps>`
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;
@@ -154,10 +148,6 @@ const SubmitButton = styled.button`
top: calc(50% - 22px);
overflow: hidden;
outline: 0;
&:focus-within {
background-color: #eee;
}
`;
const Text = styled.p`
@@ -168,7 +158,7 @@ const Text = styled.p`
margin-top: 15px;
`;
const SuccessText = styled.p<ArrowProps>`
const SuccessText = styled.p<IArrowProps>`
color: #b1b1b1;
font-size: 1rem;
font-weight: 300;
@@ -185,7 +175,7 @@ const SuccessText = styled.p<ArrowProps>`
transition-delay: 0.55s;
`;
const Arrow = styled.svg<ArrowProps>`
const Arrow = styled.svg<IArrowProps>`
transform: ${props => props.isSubmitted && `translateX(44px)`};
transition: transform 0.25s ease-in-out;
`;