@navinc/base-react-components
Version:
Nav's Pattern Library
123 lines (112 loc) • 3.29 kB
JavaScript
import React, { useState } from 'react'
import Banner from './banner.js'
import styled, { useTheme } from 'styled-components'
import PropTypes from 'prop-types'
import isRebrand from './is-rebrand.js'
const TimedBar = styled.div`
@keyframes animate {
from {
width: 100%;
}
to {
width: 0%;
}
}
animation-name: 'animate';
animation-play-state: ${({ isAnimationRunning, shouldNotTimeout }) =>
!shouldNotTimeout && isAnimationRunning ? 'running' : 'paused'};
animation-duration: ${({ time }) => `${time}ms`};
background-color: ${({ backgroundColor, theme }) => theme[backgroundColor]};
height: 5px;
position: absolute;
bottom: 0;
border-radius: ${({ shouldNotTimeout }) => (shouldNotTimeout ? '0 0 4px 4px' : '0 0 0 4px')};
`
const Container = styled.div`
position: relative;
width: 100%;
`
const deprecatedExpandedStyles = {
error: {
primaryColor: 'sebastianRed200',
secondaryColor: 'sebastianRed100',
defaultIcon: 'actions/circle-warning',
defaultActionIcon: 'actions/close',
},
neutralAction: {
primaryColor: 'bubbleBlue400',
secondaryColor: 'bubbleBlue100',
defaultIcon: 'actions/circle-info',
defaultActionIcon: 'actions/carrot-right',
},
success: {
primaryColor: 'seaturtleGreen200',
secondaryColor: 'seaturtleGreen100',
defaultIcon: 'actions/check-circle',
defaultActionIcon: 'actions/close',
},
}
const expandedStyles = {
error: {
primaryColor: 'navStatusNegative',
secondaryColor: 'navStatusNegative200',
defaultIcon: 'actions/circle-warning',
defaultActionIcon: 'actions/close',
},
neutralAction: {
primaryColor: 'navNeutral400',
secondaryColor: 'navNeutral100',
defaultIcon: 'actions/circle-info',
defaultActionIcon: 'actions/carrot-right',
},
success: {
primaryColor: 'navStatusPositive',
secondaryColor: 'navStatusPositive200',
defaultIcon: 'actions/check-circle',
defaultActionIcon: 'actions/close',
},
}
const FIVE_SECONDS = 5000
const BannerToast = ({
onDismiss,
shouldNotTimeout,
type = 'neutralAction',
time = FIVE_SECONDS,
shouldShowTimedBar = true,
...props
}) => {
const theme = useTheme()
const styles = isRebrand(theme) ? expandedStyles : deprecatedExpandedStyles
const [isAnimationRunning, setIsAnimationRunning] = useState(true)
const handleMouseOver = () => setIsAnimationRunning(false)
const handleMouseOut = () => setIsAnimationRunning(true)
const { primaryColor } = styles[type] ?? styles.neutralAction
return (
<Container onMouseOver={handleMouseOver} onMouseOut={handleMouseOut}>
<Banner
expandedStyles={styles}
onDismiss={shouldNotTimeout && onDismiss}
shouldHideBorder
type={type}
time={time}
{...props}
/>
{shouldShowTimedBar && (
<TimedBar
isAnimationRunning={isAnimationRunning}
onAnimationEnd={onDismiss}
time={time}
backgroundColor={primaryColor}
shouldNotTimeout={shouldNotTimeout}
data-testid="BannerToast:AnimationBar"
/>
)}
</Container>
)
}
BannerToast.propTypes = {
onDismiss: PropTypes.func,
shouldNotTimeout: PropTypes.bool,
time: PropTypes.number,
}
export default BannerToast