From 2c585bfbdc4940e3e6089ac1cf595dd009b141d2 Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Fri, 9 Nov 2018 15:15:57 -0800 Subject: feat(instant): Dismissible overlay error messages Adds dismissible overlay to error messages on mobile --- packages/instant/src/components/ui/overlay.tsx | 12 +++++-- packages/instant/src/containers/latest_error.tsx | 41 +++++++++++++++++++----- packages/instant/src/style/media.ts | 2 +- packages/instant/src/style/theme.ts | 5 ++- packages/instant/src/style/z_index.ts | 1 + packages/instant/src/types.ts | 1 + 6 files changed, 50 insertions(+), 12 deletions(-) (limited to 'packages/instant') diff --git a/packages/instant/src/components/ui/overlay.tsx b/packages/instant/src/components/ui/overlay.tsx index c5f55f9c0..f67d6fb2f 100644 --- a/packages/instant/src/components/ui/overlay.tsx +++ b/packages/instant/src/components/ui/overlay.tsx @@ -1,11 +1,15 @@ import * as _ from 'lodash'; -import { overlayBlack, styled } from '../../style/theme'; +import { generateMediaWrapper, ScreenWidths } from '../../style/media'; +import { generateOverlayBlack, styled } from '../../style/theme'; import { zIndex } from '../../style/z_index'; export interface OverlayProps { zIndex?: number; backgroundColor?: string; + width?: string; + height?: string; + showMaxWidth?: ScreenWidths; } export const Overlay = @@ -20,12 +24,16 @@ export const Overlay = left: 0; z-index: ${props => props.zIndex} background-color: ${props => props.backgroundColor}; + ${props => props.width && `width: ${props.width};`} + ${props => props.height && `height: ${props.height};`} + display: ${props => (props.showMaxWidth ? 'none' : 'block')}; + ${props => props.showMaxWidth && generateMediaWrapper(props.showMaxWidth)`display: block;`} } `; Overlay.defaultProps = { zIndex: zIndex.overlayDefault, - backgroundColor: overlayBlack, + backgroundColor: generateOverlayBlack(0.6), }; Overlay.displayName = 'Overlay'; diff --git a/packages/instant/src/containers/latest_error.tsx b/packages/instant/src/containers/latest_error.tsx index 99e55a6c4..c0da181f1 100644 --- a/packages/instant/src/containers/latest_error.tsx +++ b/packages/instant/src/containers/latest_error.tsx @@ -1,35 +1,60 @@ import * as React from 'react'; import { connect } from 'react-redux'; +import { Dispatch } from 'redux'; import { SlideAnimationState } from '../components/animations/slide_animation'; import { SlidingError } from '../components/sliding_error'; +import { Overlay } from '../components/ui/overlay'; +import { Action } from '../redux/actions'; import { State } from '../redux/reducer'; -import { Asset, DisplayStatus } from '../types'; +import { ScreenWidths } from '../style/media'; +import { generateOverlayBlack } from '../style/theme'; +import { zIndex } from '../style/z_index'; +import { Asset, DisplayStatus, Omit } from '../types'; +import { errorFlasher } from '../util/error_flasher'; export interface LatestErrorComponentProps { asset?: Asset; latestErrorMessage?: string; animationState: SlideAnimationState; + shouldRenderOverlay: boolean; + onOverlayClick: () => void; } export const LatestErrorComponent: React.StatelessComponent = props => { if (!props.latestErrorMessage) { return
; } - return ; + return ( + + + {props.shouldRenderOverlay && ( + + )} + + ); }; -interface ConnectedState { - asset?: Asset; - latestErrorMessage?: string; - animationState: SlideAnimationState; -} export interface LatestErrorProps {} +interface ConnectedState extends Omit {} const mapStateToProps = (state: State, _ownProps: LatestErrorProps): ConnectedState => ({ asset: state.selectedAsset, latestErrorMessage: state.latestErrorMessage, animationState: state.latestErrorDisplayStatus === DisplayStatus.Present ? 'slidIn' : 'slidOut', + shouldRenderOverlay: state.latestErrorDisplayStatus === DisplayStatus.Present, +}); + +type ConnectedDispatch = Pick; +const mapDispatchToProps = (dispatch: Dispatch, _ownProps: LatestErrorProps): ConnectedDispatch => ({ + onOverlayClick: () => { + errorFlasher.clearError(dispatch); + }, }); -export const LatestError = connect(mapStateToProps)(LatestErrorComponent); +export const LatestError = connect(mapStateToProps, mapDispatchToProps)(LatestErrorComponent); diff --git a/packages/instant/src/style/media.ts b/packages/instant/src/style/media.ts index 5e7aaba37..bbf376694 100644 --- a/packages/instant/src/style/media.ts +++ b/packages/instant/src/style/media.ts @@ -8,7 +8,7 @@ export enum ScreenWidths { Lg = 64, } -const generateMediaWrapper = (screenWidth: ScreenWidths) => (...args: any[]) => css` +export const generateMediaWrapper = (screenWidth: ScreenWidths) => (...args: any[]) => css` @media (max-width: ${screenWidth}em) { ${css.apply(css, args)}; } diff --git a/packages/instant/src/style/theme.ts b/packages/instant/src/style/theme.ts index 2653c38f7..1e9f55e00 100644 --- a/packages/instant/src/style/theme.ts +++ b/packages/instant/src/style/theme.ts @@ -35,7 +35,10 @@ export const theme: Theme = { }; export const transparentWhite = 'rgba(255,255,255,0.3)'; -export const overlayBlack = 'rgba(0, 0, 0, 0.6)'; export const completelyTransparent = 'rga(0, 0, 0, 0)'; +export const generateOverlayBlack = (opacity = 0.6) => { + return `rgba(0, 0, 0, ${opacity})`; +}; + export { styled, css, keyframes, withTheme, createGlobalStyle, ThemeProvider }; diff --git a/packages/instant/src/style/z_index.ts b/packages/instant/src/style/z_index.ts index bd034182e..ba2d27a17 100644 --- a/packages/instant/src/style/z_index.ts +++ b/packages/instant/src/style/z_index.ts @@ -3,6 +3,7 @@ export const zIndex = { mainContainer: 20, dropdownItems: 30, panel: 40, + containerOverlay: 45, errorPopup: 50, overlayDefault: 100, }; diff --git a/packages/instant/src/types.ts b/packages/instant/src/types.ts index 20ad2ed95..62afe652d 100644 --- a/packages/instant/src/types.ts +++ b/packages/instant/src/types.ts @@ -4,6 +4,7 @@ import { Web3Wrapper } from '@0x/web3-wrapper'; import { Provider } from 'ethereum-types'; // Reusable +export type Omit = Pick>; export type Maybe = T | undefined; export enum AsyncProcessState { None = 'NONE', -- cgit v1.2.3