aboutsummaryrefslogtreecommitdiffstats
path: root/packages/website/ts/components/ui
diff options
context:
space:
mode:
Diffstat (limited to 'packages/website/ts/components/ui')
-rw-r--r--packages/website/ts/components/ui/animation.tsx42
-rw-r--r--packages/website/ts/components/ui/check_mark.tsx31
-rw-r--r--packages/website/ts/components/ui/container.tsx43
-rw-r--r--packages/website/ts/components/ui/ease_up_from_bottom_animation.tsx31
-rw-r--r--packages/website/ts/components/ui/filled_image.tsx18
-rw-r--r--packages/website/ts/components/ui/image.tsx2
-rw-r--r--packages/website/ts/components/ui/input.tsx43
-rw-r--r--packages/website/ts/components/ui/multi_select.tsx66
-rw-r--r--packages/website/ts/components/ui/simple_loading.tsx17
-rw-r--r--packages/website/ts/components/ui/text.tsx3
-rw-r--r--packages/website/ts/components/ui/typed_text.tsx75
11 files changed, 173 insertions, 198 deletions
diff --git a/packages/website/ts/components/ui/animation.tsx b/packages/website/ts/components/ui/animation.tsx
deleted file mode 100644
index 943e3bf28..000000000
--- a/packages/website/ts/components/ui/animation.tsx
+++ /dev/null
@@ -1,42 +0,0 @@
-import * as React from 'react';
-import { keyframes, styled } from 'ts/style/theme';
-
-export type AnimationType = 'easeUpFromBottom';
-
-export interface AnimationProps {
- type: AnimationType;
-}
-
-const PlainAnimation: React.StatelessComponent<AnimationProps> = props => <div {...props} />;
-
-const appearFromBottomFrames = keyframes`
- from {
- position: fixed;
- bottom: -500px;
- left: 0px;
- right: 0px;
- }
-
- to {
- position: fixed;
- bottom: 0px;
- left: 0px;
- right: 0px;
- }
-`;
-
-const stylesForAnimation: { [K in AnimationType]: string } = {
- // Needed for safari
- easeUpFromBottom: `position: fixed`,
-};
-
-const animations: { [K in AnimationType]: string } = {
- easeUpFromBottom: `${appearFromBottomFrames} 1s ease 0s 1 forwards`,
-};
-
-export const Animation = styled(PlainAnimation)`
- animation: ${props => animations[props.type]};
- ${props => stylesForAnimation[props.type]};
-`;
-
-Animation.displayName = 'Animation';
diff --git a/packages/website/ts/components/ui/check_mark.tsx b/packages/website/ts/components/ui/check_mark.tsx
new file mode 100644
index 000000000..86e427c8b
--- /dev/null
+++ b/packages/website/ts/components/ui/check_mark.tsx
@@ -0,0 +1,31 @@
+import * as React from 'react';
+
+import { colors } from '@0x/react-shared';
+
+export interface CheckMarkProps {
+ color?: string;
+ isChecked?: boolean;
+}
+
+export const CheckMark: React.StatelessComponent<CheckMarkProps> = ({ color, isChecked }) => (
+ <svg width="17" height="17" viewBox="0 0 17 17" fill="none" xmlns="http://www.w3.org/2000/svg">
+ <circle
+ cx="8.5"
+ cy="8.5"
+ r="8.5"
+ fill={isChecked ? color : 'white'}
+ stroke={isChecked ? undefined : '#CCCCCC'}
+ />
+ <path
+ d="M2.5 4.5L1.79289 5.20711L2.5 5.91421L3.20711 5.20711L2.5 4.5ZM-0.707107 2.70711L1.79289 5.20711L3.20711 3.79289L0.707107 1.29289L-0.707107 2.70711ZM3.20711 5.20711L7.70711 0.707107L6.29289 -0.707107L1.79289 3.79289L3.20711 5.20711Z"
+ transform="translate(5 6.5)"
+ fill="white"
+ />
+ </svg>
+);
+
+CheckMark.displayName = 'Check';
+
+CheckMark.defaultProps = {
+ color: colors.mediumBlue,
+};
diff --git a/packages/website/ts/components/ui/container.tsx b/packages/website/ts/components/ui/container.tsx
index 7eab2a50f..778f59f27 100644
--- a/packages/website/ts/components/ui/container.tsx
+++ b/packages/website/ts/components/ui/container.tsx
@@ -1,11 +1,15 @@
import { TextAlignProperty } from 'csstype';
+import { darken } from 'polished';
import * as React from 'react';
+import { styled } from 'ts/style/theme';
+
type StringOrNum = string | number;
export type ContainerTag = 'div' | 'span';
export interface ContainerProps {
+ margin?: string;
marginTop?: StringOrNum;
marginBottom?: StringOrNum;
marginRight?: StringOrNum;
@@ -17,10 +21,14 @@ export interface ContainerProps {
paddingLeft?: StringOrNum;
backgroundColor?: string;
background?: string;
+ border?: string;
+ borderTop?: string;
borderRadius?: StringOrNum;
borderBottomLeftRadius?: StringOrNum;
borderBottomRightRadius?: StringOrNum;
borderBottom?: StringOrNum;
+ borderColor?: string;
+ children?: React.ReactNode;
maxWidth?: StringOrNum;
maxHeight?: StringOrNum;
width?: StringOrNum;
@@ -37,15 +45,32 @@ export interface ContainerProps {
right?: string;
bottom?: string;
zIndex?: number;
+ float?: 'right' | 'left';
Tag?: ContainerTag;
cursor?: string;
id?: string;
onClick?: (event: React.MouseEvent<HTMLElement>) => void;
overflowX?: 'scroll' | 'hidden' | 'auto' | 'visible';
+ overflowY?: 'scroll' | 'hidden' | 'auto' | 'visible';
+ shouldDarkenOnHover?: boolean;
+ hasBoxShadow?: boolean;
+ shouldAddBoxShadowOnHover?: boolean;
}
-export const Container: React.StatelessComponent<ContainerProps> = props => {
- const { children, className, Tag, isHidden, id, onClick, ...style } = props;
+export const PlainContainer: React.StatelessComponent<ContainerProps> = props => {
+ const {
+ children,
+ className,
+ Tag,
+ isHidden,
+ id,
+ onClick,
+ shouldDarkenOnHover,
+ shouldAddBoxShadowOnHover,
+ hasBoxShadow,
+ // tslint:disable-next-line:trailing-comma
+ ...style
+ } = props;
const visibility = isHidden ? 'hidden' : undefined;
return (
<Tag id={id} style={{ ...style, visibility }} className={className} onClick={onClick}>
@@ -54,6 +79,20 @@ export const Container: React.StatelessComponent<ContainerProps> = props => {
);
};
+const BOX_SHADOW = '0px 3px 10px rgba(0, 0, 0, 0.3)';
+
+export const Container = styled(PlainContainer)`
+ box-sizing: border-box;
+ ${props => (props.hasBoxShadow ? `box-shadow: ${BOX_SHADOW}` : '')};
+ &:hover {
+ ${props =>
+ props.shouldDarkenOnHover
+ ? `background-color: ${props.backgroundColor ? darken(0.05, props.backgroundColor) : 'none'} !important`
+ : ''};
+ ${props => (props.shouldAddBoxShadowOnHover ? `box-shadow: ${BOX_SHADOW}` : '')};
+ }
+`;
+
Container.defaultProps = {
Tag: 'div',
};
diff --git a/packages/website/ts/components/ui/ease_up_from_bottom_animation.tsx b/packages/website/ts/components/ui/ease_up_from_bottom_animation.tsx
new file mode 100644
index 000000000..ba141c01e
--- /dev/null
+++ b/packages/website/ts/components/ui/ease_up_from_bottom_animation.tsx
@@ -0,0 +1,31 @@
+import { css, keyframes, styled } from 'ts/style/theme';
+
+const appearFromBottomFrames = keyframes`
+ from {
+ position: fixed;
+ bottom: -500px;
+ left: 0px;
+ right: 0px;
+ }
+
+ to {
+ position: fixed;
+ bottom: 0px;
+ left: 0px;
+ right: 0px;
+ }
+`;
+
+const stylesForAnimation = css`
+ position: fixed;
+`;
+const animations = css`
+ animation: ${appearFromBottomFrames} 1s ease 0s 1 forwards;
+`;
+
+export const EaseUpFromBottomAnimation = styled.div`
+ ${props => animations};
+ ${props => stylesForAnimation};
+`;
+
+EaseUpFromBottomAnimation.displayName = 'EaseUpFromBottomAnimation';
diff --git a/packages/website/ts/components/ui/filled_image.tsx b/packages/website/ts/components/ui/filled_image.tsx
deleted file mode 100644
index 7f58ee5b9..000000000
--- a/packages/website/ts/components/ui/filled_image.tsx
+++ /dev/null
@@ -1,18 +0,0 @@
-import * as React from 'react';
-
-export interface FilledImageProps {
- src: string;
-}
-export const FilledImage = (props: FilledImageProps) => (
- <div
- style={{
- width: '100%',
- height: '100%',
- objectFit: 'cover',
- backgroundImage: `url(${props.src})`,
- backgroundRepeat: 'no-repeat',
- backgroundPosition: 'center',
- backgroundSize: 'cover',
- }}
- />
-);
diff --git a/packages/website/ts/components/ui/image.tsx b/packages/website/ts/components/ui/image.tsx
index c8d39352b..d698ddaa0 100644
--- a/packages/website/ts/components/ui/image.tsx
+++ b/packages/website/ts/components/ui/image.tsx
@@ -10,6 +10,7 @@ export interface ImageProps {
height?: string | number;
maxWidth?: string | number;
maxHeight?: string | number;
+ additionalStyle?: React.CSSProperties;
}
interface ImageState {
imageLoadFailed: boolean;
@@ -30,6 +31,7 @@ export class Image extends React.Component<ImageProps, ImageState> {
onError={this._onError.bind(this)}
src={src}
style={{
+ ...this.props.additionalStyle,
borderRadius: this.props.borderRadius,
maxWidth: this.props.maxWidth,
maxHeight: this.props.maxHeight,
diff --git a/packages/website/ts/components/ui/input.tsx b/packages/website/ts/components/ui/input.tsx
deleted file mode 100644
index e5f4f6c70..000000000
--- a/packages/website/ts/components/ui/input.tsx
+++ /dev/null
@@ -1,43 +0,0 @@
-import { colors } from '@0x/react-shared';
-import * as React from 'react';
-import { styled } from 'ts/style/theme';
-
-export interface InputProps {
- className?: string;
- value?: string;
- width?: string;
- fontSize?: string;
- fontColor?: string;
- placeholderColor?: string;
- placeholder?: string;
- backgroundColor?: string;
- onChange?: (event: React.ChangeEvent<HTMLInputElement>) => void;
-}
-
-const PlainInput: React.StatelessComponent<InputProps> = ({ value, className, placeholder, onChange }) => (
- <input className={className} value={value} onChange={onChange} placeholder={placeholder} />
-);
-
-export const Input = styled(PlainInput)`
- font-size: ${props => props.fontSize};
- width: ${props => props.width};
- padding: 0.8em 1.2em;
- border-radius: 3px;
- font-family: 'Roboto Mono';
- color: ${props => props.fontColor};
- border: none;
- background-color: ${props => props.backgroundColor};
- &::placeholder {
- color: ${props => props.placeholderColor};
- }
-`;
-
-Input.defaultProps = {
- width: 'auto',
- backgroundColor: colors.white,
- fontColor: colors.darkestGrey,
- placeholderColor: colors.darkGrey,
- fontSize: '12px',
-};
-
-Input.displayName = 'Input';
diff --git a/packages/website/ts/components/ui/multi_select.tsx b/packages/website/ts/components/ui/multi_select.tsx
new file mode 100644
index 000000000..2cf44cae1
--- /dev/null
+++ b/packages/website/ts/components/ui/multi_select.tsx
@@ -0,0 +1,66 @@
+import { colors } from '@0x/react-shared';
+import * as _ from 'lodash';
+import * as React from 'react';
+
+import { Container } from './container';
+
+export interface MultiSelectItemConfig {
+ value: string;
+ renderItemContent: (isSelected: boolean) => React.ReactNode;
+ onClick?: () => void;
+}
+
+export interface MultiSelectProps {
+ selectedValues?: string[];
+ items: MultiSelectItemConfig[];
+ backgroundColor?: string;
+ height?: string;
+}
+
+export class MultiSelect extends React.Component<MultiSelectProps> {
+ public static defaultProps = {
+ backgroundColor: colors.white,
+ };
+ public render(): React.ReactNode {
+ const { items, backgroundColor, selectedValues, height } = this.props;
+ return (
+ <Container
+ backgroundColor={backgroundColor}
+ borderRadius="4px"
+ width="100%"
+ height={height}
+ overflowY="scroll"
+ >
+ {_.map(items, item => (
+ <MultiSelectItem
+ key={item.value}
+ renderItemContent={item.renderItemContent}
+ backgroundColor={backgroundColor}
+ onClick={item.onClick}
+ isSelected={_.isUndefined(selectedValues) || _.includes(selectedValues, item.value)}
+ />
+ ))}
+ </Container>
+ );
+ }
+}
+
+export interface MultiSelectItemProps {
+ renderItemContent: (isSelected: boolean) => React.ReactNode;
+ isSelected?: boolean;
+ onClick?: () => void;
+ backgroundColor?: string;
+}
+
+export const MultiSelectItem: React.StatelessComponent<MultiSelectItemProps> = ({
+ renderItemContent,
+ isSelected,
+ onClick,
+ backgroundColor,
+}) => (
+ <Container cursor="pointer" shouldDarkenOnHover={true} onClick={onClick} backgroundColor={backgroundColor}>
+ <Container borderBottom={`1px solid ${colors.lightestGrey}`} margin="0px 15px" padding="10px 0px">
+ {renderItemContent(isSelected)}
+ </Container>
+ </Container>
+);
diff --git a/packages/website/ts/components/ui/simple_loading.tsx b/packages/website/ts/components/ui/simple_loading.tsx
deleted file mode 100644
index 81744196d..000000000
--- a/packages/website/ts/components/ui/simple_loading.tsx
+++ /dev/null
@@ -1,17 +0,0 @@
-import CircularProgress from 'material-ui/CircularProgress';
-import * as React from 'react';
-
-export interface SimpleLoadingProps {
- message: string;
-}
-
-export const SimpleLoading = (props: SimpleLoadingProps) => {
- return (
- <div className="mx-auto pt3" style={{ maxWidth: 400, height: 409 }}>
- <div className="relative" style={{ top: '50%', transform: 'translateY(-50%)', height: 95 }}>
- <CircularProgress />
- <div className="pt3 pb3">{props.message}</div>
- </div>
- </div>
- );
-};
diff --git a/packages/website/ts/components/ui/text.tsx b/packages/website/ts/components/ui/text.tsx
index c13e21913..046442ee5 100644
--- a/packages/website/ts/components/ui/text.tsx
+++ b/packages/website/ts/components/ui/text.tsx
@@ -3,10 +3,11 @@ import { darken } from 'polished';
import * as React from 'react';
import { styled } from 'ts/style/theme';
-export type TextTag = 'p' | 'div' | 'span' | 'label' | 'h1' | 'h2' | 'h3' | 'h4' | 'i';
+export type TextTag = 'p' | 'div' | 'span' | 'label' | 'h1' | 'h2' | 'h3' | 'h4' | 'i' | 'span';
export interface TextProps {
className?: string;
+ children?: any;
Tag?: TextTag;
fontSize?: string;
fontFamily?: string;
diff --git a/packages/website/ts/components/ui/typed_text.tsx b/packages/website/ts/components/ui/typed_text.tsx
deleted file mode 100644
index 6d38580b9..000000000
--- a/packages/website/ts/components/ui/typed_text.tsx
+++ /dev/null
@@ -1,75 +0,0 @@
-import * as _ from 'lodash';
-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,
- // tslint:disable-next-line
- ...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,
- });
- }
- }
-}