import { ReactNode, useRef } from 'react'; import { useTheme } from 'styled-components'; import { Box } from '../box/Box'; import { Button } from '../buttonv2/Buttonv2.component'; import { Icon } from '../icon/Icon.component'; import { BasicText } from '../text/Text.component'; import { ToastPosition, positionOutput } from './ToastPositionHelpers'; import { DurationBasedProgressBar } from './DurationBasedProgressBar'; import { useToastParameters } from './useToastParameters'; import styled from 'styled-components'; export type ToastStatus = 'success' | 'error' | 'warning' | 'info'; export type ToastProps = { open: boolean; message: ReactNode; onClose: () => void; status?: ToastStatus; position?: ToastPosition; autoDismiss?: boolean; duration?: number; icon?: React.ReactNode; width?: React.CSSProperties['width']; withProgressBar?: boolean; style?: React.CSSProperties; }; export const useGetBackgroundColor = (status: string) => { const theme = useTheme(); switch (status) { case 'success': return theme.statusHealthy; case 'error': return theme.statusCritical; case 'warning': return theme.statusWarning; default: return theme.infoPrimary; } }; const useGetRgbBackgroundColor = (status: string) => { const theme = useTheme(); switch (status) { case 'success': return `rgba(${theme.statusHealthyRGB}, 0.4)`; case 'error': return `rgba(${theme.statusCriticalRGB}, 0.4)`; case 'warning': return `rgba(${theme.statusWarningRGB}, 0.4)`; default: return theme.infoSecondary; } }; const defaultIconName = (status: string) => { switch (status) { case 'success': return 'Check-circle'; case 'error': return 'Times-circle'; case 'warning': return 'Exclamation-circle'; default: return 'Info-circle'; } }; const DefaultIcon = ({ status }: { status: string }) => { const color = useGetBackgroundColor(status); const iconName = defaultIconName(status); return ; }; const DEFAULT_WIDTH = '25rem'; const IconContainer = styled.div<{ bgColor: string }>` align-items: center; align-self: stretch; border-radius: 4px 0px 0px 4px; display: flex; gap: 16px; justify-content: center; position: relative; width: 32px; background-color: ${(props) => props.bgColor}; `; const ContentContainer = styled.div` align-items: center; align-self: stretch; display: flex; flex: 1; flex-grow: 1; gap: 8px; padding: 0px 16px; position: relative; `; const FadingToast = styled.div` align-items: flex-end; background-color: ${props => props.theme.backgroundLevel1}; border: 1px solid ${props => props.theme.border}; box-shadow: 0px 4px 10px 4px #000; display: flex; border-radius: 4px; position: relative; @keyframes toastEnter { from { opacity: 0; transform: translateY(-20px); } to { opacity: 1; transform: translateY(0); } } `; const ToastEnter = styled(FadingToast)` animation: toastEnter 0.3s ease forwards; `; function Toast({ open, message, onClose, position = 'top-right', status = 'info', autoDismiss = true, duration = 5000, icon = , width = DEFAULT_WIDTH, withProgressBar = false, style, }: ToastProps) { const ref = useRef(null); const { params } = useToastParameters({ open, duration: autoDismiss ? duration : null, onClose, }); const positionStyle = positionOutput[position]; const bgColor = useGetBackgroundColor(status); const rgbBgColor = useGetRgbBackgroundColor(status); if (!open) { return null; } return (
{icon} {message}
); } export { Toast };