5 changed files with 171 additions and 78 deletions
@ -0,0 +1,129 @@ |
|||
// @flow
|
|||
|
|||
import React, { PureComponent } from 'react' |
|||
import styled from 'styled-components' |
|||
import { connect } from 'react-redux' |
|||
import Box from 'components/base/Box' |
|||
import { radii } from 'styles/theme' |
|||
import IconCross from 'icons/Cross' |
|||
import { createStructuredSelector } from 'reselect' |
|||
import { dismissBanner } from '../actions/settings' |
|||
import { dismissedBannersSelector } from '../reducers/settings' |
|||
|
|||
export type Content = { |
|||
Icon?: React$ComponentType<*>, |
|||
message: React$Node, |
|||
right?: React$Node, |
|||
} |
|||
|
|||
type Props = { |
|||
content?: Content, |
|||
status: string, |
|||
dismissable: boolean, |
|||
bannerId?: string, |
|||
dismissedBanners: string[], |
|||
dismissBanner: string => void, |
|||
} |
|||
|
|||
const mapStateToProps = createStructuredSelector({ |
|||
dismissedBanners: dismissedBannersSelector, |
|||
}) |
|||
|
|||
const mapDispatchToProps = { |
|||
dismissBanner, |
|||
} |
|||
|
|||
class TopBanner extends PureComponent<Props> { |
|||
static defaultProps = { |
|||
status: '', |
|||
dismissable: false, |
|||
} |
|||
|
|||
onDismiss = () => { |
|||
const { bannerId, dismissBanner } = this.props |
|||
|
|||
if (bannerId) { |
|||
dismissBanner(bannerId) |
|||
} |
|||
} |
|||
|
|||
render() { |
|||
const { dismissedBanners, bannerId, dismissable, content, status } = this.props |
|||
|
|||
if (!content || (bannerId && dismissedBanners.includes(bannerId))) return null |
|||
|
|||
const { Icon, message, right } = content |
|||
|
|||
return ( |
|||
<Container status={status}> |
|||
{Icon && ( |
|||
<IconContainer> |
|||
<Icon size={16} /> |
|||
</IconContainer> |
|||
)} |
|||
{message} |
|||
<RightContainer>{right}</RightContainer> |
|||
{dismissable && ( |
|||
<CloseContainer onClick={this.onDismiss}> |
|||
<IconCross size={16} /> |
|||
</CloseContainer> |
|||
)} |
|||
</Container> |
|||
) |
|||
} |
|||
} |
|||
|
|||
export default connect( |
|||
mapStateToProps, |
|||
mapDispatchToProps, |
|||
)(TopBanner) |
|||
|
|||
const IconContainer = styled.div` |
|||
margin-right: 15px; |
|||
display: flex; |
|||
align-items: center; |
|||
` |
|||
|
|||
const colorForStatus = { |
|||
error: 'alertRed', |
|||
} |
|||
|
|||
const Container = styled(Box).attrs({ |
|||
horizontal: true, |
|||
align: 'center', |
|||
py: '8px', |
|||
px: 3, |
|||
bg: p => colorForStatus[p.status] || 'wallet', |
|||
color: 'white', |
|||
mt: -20, |
|||
mb: 20, |
|||
fontSize: 4, |
|||
ff: 'Open Sans|SemiBold', |
|||
})` |
|||
border-radius: ${radii[1]}px; |
|||
` |
|||
|
|||
const RightContainer = styled.div` |
|||
margin-left: auto; |
|||
` |
|||
|
|||
export const FakeLink = styled.span` |
|||
color: white; |
|||
text-decoration: underline; |
|||
cursor: pointer; |
|||
` |
|||
|
|||
const CloseContainer = styled(Box).attrs({ |
|||
color: 'white', |
|||
})` |
|||
z-index: 1; |
|||
margin-left: 10px; |
|||
cursor: pointer; |
|||
&:hover { |
|||
color: ${p => p.theme.colors.graphite}; |
|||
} |
|||
|
|||
&:active { |
|||
color: ${p => p.theme.colors.graphite}; |
|||
} |
|||
` |
Loading…
Reference in new issue