Add TypedText component and use it on landing page
This commit is contained in:
1
packages/typescript-typings/types/react-typist/index.d.ts
vendored
Normal file
1
packages/typescript-typings/types/react-typist/index.d.ts
vendored
Normal file
@@ -0,0 +1 @@
|
||||
declare module 'react-typist';
|
||||
@@ -52,6 +52,7 @@
|
||||
"react-router-dom": "^4.1.1",
|
||||
"react-scroll": "0xproject/react-scroll#similar-to-pr-330",
|
||||
"react-tooltip": "^3.2.7",
|
||||
"react-typist": "^2.0.4",
|
||||
"redux": "^3.6.0",
|
||||
"redux-devtools-extension": "^2.13.2",
|
||||
"semver-sort": "0.0.4",
|
||||
|
||||
@@ -20,6 +20,7 @@ export interface TextProps {
|
||||
onClick?: (event: React.MouseEvent<HTMLElement>) => void;
|
||||
hoverColor?: string;
|
||||
noWrap?: boolean;
|
||||
display?: string;
|
||||
}
|
||||
|
||||
const PlainText: React.StatelessComponent<TextProps> = ({ children, className, onClick, Tag }) => (
|
||||
@@ -41,6 +42,7 @@ export const Text = styled(PlainText)`
|
||||
${props => (props.onClick ? 'cursor: pointer' : '')};
|
||||
transition: color 0.5s ease;
|
||||
${props => (props.noWrap ? 'white-space: nowrap' : '')};
|
||||
${props => (props.display ? `display: ${props.display}` : '')};
|
||||
&:hover {
|
||||
${props => (props.onClick ? `color: ${props.hoverColor || darken(0.3, props.fontColor)}` : '')};
|
||||
}
|
||||
|
||||
75
packages/website/ts/components/ui/typed_text.tsx
Normal file
75
packages/website/ts/components/ui/typed_text.tsx
Normal file
@@ -0,0 +1,75 @@
|
||||
import * as _ from 'lodash';
|
||||
import { darken } from 'polished';
|
||||
import * as React from 'react';
|
||||
import Typist from 'react-typist';
|
||||
|
||||
import { Text, TextProps } from 'ts/components/ui/text';
|
||||
|
||||
import 'react-typist/dist/Typist.css';
|
||||
|
||||
export interface TypedTextProps extends TextProps {
|
||||
textList: string[];
|
||||
shouldRepeat?: boolean;
|
||||
wordDelayMs?: number;
|
||||
avgKeystrokeDelayMs?: number;
|
||||
stdKeystrokeDelay?: number;
|
||||
}
|
||||
|
||||
export interface TypedTextState {
|
||||
cycleCount: number;
|
||||
}
|
||||
|
||||
export class TypedText extends React.Component<TypedTextProps, TypedTextState> {
|
||||
public static defaultProps = {
|
||||
shouldRepeat: false,
|
||||
avgKeystrokeDelayMs: 90,
|
||||
wordDelayMs: 1000,
|
||||
};
|
||||
public state = {
|
||||
cycleCount: 0,
|
||||
};
|
||||
public render(): React.ReactNode {
|
||||
const {
|
||||
textList,
|
||||
shouldRepeat,
|
||||
wordDelayMs,
|
||||
avgKeystrokeDelayMs,
|
||||
stdKeystrokeDelay,
|
||||
...textProps
|
||||
} = this.props;
|
||||
const { cycleCount } = this.state;
|
||||
if (_.isEmpty(textList)) {
|
||||
return null;
|
||||
}
|
||||
const typistChildren: React.ReactNode[] = [];
|
||||
_.forEach(textList, text => {
|
||||
typistChildren.push(
|
||||
<Text key={`text-${text}-${cycleCount}`} {...textProps}>
|
||||
{text}
|
||||
</Text>,
|
||||
);
|
||||
if (wordDelayMs) {
|
||||
typistChildren.push(<Typist.Delay key={`delay-${text}-${cycleCount}`} ms={wordDelayMs} />);
|
||||
}
|
||||
typistChildren.push(<Typist.Backspace key={`backspace-${text}-${cycleCount}`} count={text.length} />);
|
||||
});
|
||||
return (
|
||||
<Typist
|
||||
avgTypingDelay={avgKeystrokeDelayMs}
|
||||
stdTypingDelay={stdKeystrokeDelay}
|
||||
className="inline"
|
||||
key={`typist-key-${cycleCount}`}
|
||||
onTypingDone={this._onTypingDone.bind(this)}
|
||||
>
|
||||
{typistChildren}
|
||||
</Typist>
|
||||
);
|
||||
}
|
||||
private _onTypingDone(): void {
|
||||
if (this.props.shouldRepeat) {
|
||||
this.setState({
|
||||
cycleCount: this.state.cycleCount + 1,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -23,6 +23,7 @@ trackedTokenStorage.clearIfRequired();
|
||||
|
||||
import 'basscss/css/basscss.css';
|
||||
import 'less/all.less';
|
||||
import 'react-typist/dist/Typist.css';
|
||||
|
||||
// We pass modulePromise returning lambda instead of module promise,
|
||||
// cause we only want to import the module when the user navigates to the page.
|
||||
|
||||
@@ -10,6 +10,7 @@ import { CallToAction } from 'ts/components/ui/button';
|
||||
import { Container } from 'ts/components/ui/container';
|
||||
import { Image } from 'ts/components/ui/image';
|
||||
import { Text } from 'ts/components/ui/text';
|
||||
import { TypedText } from 'ts/components/ui/typed_text';
|
||||
import { Dispatcher } from 'ts/redux/dispatcher';
|
||||
import { Deco, Key, Language, ScreenWidths, WebsitePaths } from 'ts/types';
|
||||
import { constants } from 'ts/utils/constants';
|
||||
@@ -43,12 +44,26 @@ const THROTTLE_TIMEOUT = 100;
|
||||
const WHATS_NEW_TITLE = 'V2 of the 0x Protocol is now live!';
|
||||
// TODO: Update this url
|
||||
const WHATS_NEW_URL = 'https://blog.0xproject.com/18-ideas-for-0x-relayers-in-2018-80a1498b955f';
|
||||
<<<<<<< HEAD
|
||||
const TITLE_STYLE: React.CSSProperties = {
|
||||
fontFamily: 'Roboto Mono',
|
||||
color: colors.grey,
|
||||
fontWeight: 300,
|
||||
letterSpacing: 3,
|
||||
};
|
||||
=======
|
||||
const ROTATING_LIST = [
|
||||
'tokens',
|
||||
'game items',
|
||||
'digital art',
|
||||
'outcomes',
|
||||
'stocks',
|
||||
'derivatives',
|
||||
'loans',
|
||||
'cats',
|
||||
'Everything.',
|
||||
];
|
||||
>>>>>>> Add TypedText component and use it on landing page
|
||||
|
||||
const relayerProjects: Project[] = [
|
||||
{
|
||||
@@ -176,12 +191,29 @@ export class Landing extends React.Component<LandingProps, LandingState> {
|
||||
<Text
|
||||
className="sm-pb2"
|
||||
fontFamily="Roboto"
|
||||
display="inline-block"
|
||||
fontColor={colors.grey300}
|
||||
fontWeight={500}
|
||||
lineHeight="1.2em"
|
||||
fontSize={isSmallScreen ? '28px' : '36px'}
|
||||
>
|
||||
{this.props.translate.get(Key.TopHeader, Deco.Cap)}
|
||||
{this.props.translate.getLanguage() === Language.English && (
|
||||
<React.Fragment>
|
||||
{' '}
|
||||
for{' '}
|
||||
<TypedText
|
||||
fontFamily="Roboto"
|
||||
display="inline-block"
|
||||
fontColor={colors.white}
|
||||
fontWeight={700}
|
||||
lineHeight="1.2em"
|
||||
fontSize={isSmallScreen ? '28px' : '36px'}
|
||||
textList={ROTATING_LIST}
|
||||
shouldRepeat={true}
|
||||
/>
|
||||
</React.Fragment>
|
||||
)}
|
||||
</Text>
|
||||
<Container className="pt3 clearfix sm-mx-auto" maxWidth="390px">
|
||||
<div className="lg-pr2 md-pr2 lg-col lg-col-6 sm-center sm-col sm-col-12 mb2">
|
||||
|
||||
@@ -10991,7 +10991,7 @@ promzard@^0.3.0:
|
||||
dependencies:
|
||||
read "1"
|
||||
|
||||
prop-types@^15.5.0, prop-types@^15.6.2:
|
||||
prop-types@^15.5.0, prop-types@^15.5.10, prop-types@^15.6.2:
|
||||
version "15.6.2"
|
||||
resolved "https://registry.npmjs.org/prop-types/-/prop-types-15.6.2.tgz#05d5ca77b4453e985d60fc7ff8c859094a497102"
|
||||
dependencies:
|
||||
@@ -11459,6 +11459,12 @@ react-transition-group@^2.2.1:
|
||||
prop-types "^15.6.2"
|
||||
react-lifecycles-compat "^3.0.4"
|
||||
|
||||
react-typist@^2.0.4:
|
||||
version "2.0.4"
|
||||
resolved "https://registry.npmjs.org/react-typist/-/react-typist-2.0.4.tgz#e7ee4de53ead913d363d38f07b700c00ce271be0"
|
||||
dependencies:
|
||||
prop-types "^15.5.10"
|
||||
|
||||
react@^16.3.2, react@^16.4.2:
|
||||
version "16.4.2"
|
||||
resolved "https://registry.npmjs.org/react/-/react-16.4.2.tgz#2cd90154e3a9d9dd8da2991149fdca3c260e129f"
|
||||
|
||||
Reference in New Issue
Block a user