import classNames from "classnames" ; import * as React from "react" ; import { polyfill } from "react-lifecycles-compat" ; import { AbstractPureComponent2 , Classes } from "../../common" ; import { DISPLAYNAME_PREFIX , ActionProps , IntentProps , LinkProps , Props , MaybeElement } from "../../common/props" ; import { ButtonGroup } from "../button/buttonGroup" ; import { AnchorButton , Button } from "../button/buttons" ; import { Icon , IconName } from "../icon/icon" ; export type ToastProps = IToastProps ; export interface IToastProps extends Props , IntentProps { /**
     * Action rendered as a minimal `AnchorButton`. The toast is dismissed automatically when the
     * user clicks the action button. Note that the `intent` prop is ignored (the action button
     * cannot have its own intent color that might conflict with the toast's intent). Omit this
     * prop to omit the action button.
     */ action ? : ActionProps & LinkProps ; /** Name of a Blueprint UI icon (or an icon element) to render before the message. */ icon ? : IconName | MaybeElement ; /** Message to display in the body of the toast. */ message : React . ReactNode ; /**
     * Callback invoked when the toast is dismissed, either by the user or by the timeout.
     * The value of the argument indicates whether the toast was closed because the timeout expired.
     */ onDismiss ? : ( didTimeoutExpire : boolean ) => void ; default timeout ? : number ; } @ polyfill export class Toast extends AbstractPureComponent2 < IToastProps > { public static defaultProps : IToastProps = { className : "" , message : "" , timeout : 5000 , } ; public static displayName = `${ DISPLAYNAME_PREFIX }.Toast` ; public render ( ) { const { className , icon , intent , message } = this . props ; return ( < div className = { classNames ( Classes . TOAST , Classes . intentClass ( intent ) , className ) } onBlur = { this . startTimeout } onFocus = { this . clearTimeouts } onMouseEnter = { this . clearTimeouts } onMouseLeave = { this . startTimeout } tabIndex = { 0 } > < Icon icon = { icon } /> < span className = { Classes . TOAST_MESSAGE } > { message } < /span> < ButtonGroup minimal = { true } > { this . maybeRenderActionButton ( ) } < Button aria - label = "Close" icon = "cross" onClick = { this . handleCloseClick } / > < /ButtonGroup> < /div>); } public componentDidMount ( ) { this . startTimeout ( ) ; } public componentDidUpdate ( prevProps ) { if ( prevProps . timeout !== this . props . timeout ) { if ( this . props . timeout ! > 0 ) { this . startTimeout ( ) ; } else { this . clearTimeouts ( ) ; } } } public componentWillUnmount ( ) { this . clearTimeouts ( ) ; } private maybeRenderActionButton ( ) { const { action } = this . props ; if ( action == null ) { return undefined ; } else { return < AnchorButton { ... action } intent = { undefined } onClick = { this . handleActionClick } / > ; } } private handleActionClick = ( e ) => { this . props . action ?. onClick ?. ( e ) ; this . triggerDismiss ( false ) ; } ; private handleCloseClick = ( ) => this . triggerDismiss ( false ) ; private triggerDismiss ( didTimeoutExpire ) { this . clearTimeouts ( ) ; this . props . onDismiss ?. ( didTimeoutExpire ) ; } private startTimeout = ( ) => { this . clearTimeouts ( ) ; if ( this . props . timeout ! > 0 ) { this . setTimeout ( ( ) => this . triggerDismiss ( true ) , this . props . timeout ) ; } } ; }