import { darken } from 'polished'; import { useEffect, useRef, useState } from 'react'; import styled, { css } from 'styled-components'; import { spacing } from '../../spacing'; import { fontWeight, grayDarkest, black, white, grayLightest, } from '../../style/theme'; import { getThemePropSelector } from '../../utils'; import { Variant } from '../constants'; import { Icon } from '../icon/Icon.component'; export type Props = { uid: string; title: string; message?: string; variant?: Variant; dismissAfter?: number; onDismiss?: (arg0: string) => void; }; const NotificationContainer = styled.div<{ variant?: Variant }>` position: relative; padding: ${spacing.r16}; margin-top: ${spacing.r16}; border-radius: 5px; box-shadow: 0px 0px 3px ${grayDarkest}; ${(props) => { const variant = props.variant ?? 'backgroundLevel1'; const background = getThemePropSelector(variant)(props); switch (props.variant) { case 'warning': return css` background-color: ${background}; color: ${black}; `; case undefined: return css` background-color: ${background}; color: ${props.theme.textPrimary}; `; default: return css` background-color: ${background}; color: ${white}; `; } }}; `; const NotificationTitle = styled.div` padding: 0 ${spacing.r16} ${spacing.r4} 0; font-weight: ${fontWeight.bold}; `; const NotificationDismissProgress = styled.div<{ variant?: Variant; value: number; max: number; }>` position: absolute; bottom: 0; left: 0; height: 5px; border-radius: 5px; ${(props) => { const variant = props.variant || 'backgroundLevel1'; const background = getThemePropSelector(variant)(props); const brandDark = darken(0.1, background); return css` background-color: ${brandDark}; width: ${(props.value / props.max) * 100}%; transition: width 1s; transition-timing-function: linear; `; }}; `; const NotificationClose = styled.div` position: absolute; top: 15px; right: 15px; cursor: pointer; &:hover { color: ${grayLightest}; } `; function Notification({ uid, title, message, variant, dismissAfter, onDismiss, ...rest }: Props) { const [dismissProgress, setDismissProgress] = useState(0); const [timerId, setTimerId] = useState(undefined); const dismissProgressRef = useRef(dismissProgress); dismissProgressRef.current = dismissProgress; useEffect(() => { resumeTimer(); }); const clearTimer = () => { if (dismissAfter) { setTimerId(undefined); clearTimeout(timerId); } }; const resumeTimer = () => { if (dismissAfter) { if (dismissProgressRef.current === dismissAfter) { dismiss(); } else if (!timerId) { setTimerId( //@ts-ignore node typing detected here instead of Dom one setTimeout(() => { setDismissProgress(dismissProgressRef.current + 1000); resumeTimer(); }, 1000), ); } } }; const dismiss = () => { if (timerId) { clearTimer(); } onDismiss && onDismiss(uid); }; return ( {title}
{message}
{!!dismissAfter && ( )}
); } export { Notification };