UNPKG

azure-devops-ui

Version:

React components for building web UI in Azure DevOps

65 lines (64 loc) 3.53 kB
import "../../CommonImports"; import "../../Core/core.css"; import "./Toast.css"; import * as React from "react"; import { makeCancelable } from '../../Core/Util/Promise'; import { Button } from '../../Button'; import { Callout, ContentJustification, ContentLocation } from '../../Callout'; import { Measure } from '../../Measure'; import { css, getSafeId, KeyCode } from '../../Util'; export class Toast extends React.Component { constructor(props) { super(props); this.callToActionRef = React.createRef(); this.onCallToActionClick = (event) => { if (this.props.onCallToActionClick) { this.props.onCallToActionClick(event); } }; this.onKeyboardShortcut = (event) => { if (this.callToActionRef.current && !this.state.fadingOut && event.ctrlKey && event.altKey && event.which === KeyCode.t) { this.callToActionRef.current.focus(); } }; // Be careful to avoid layout thrashing here; the call to action must NOT change width on re-render this.onMeasureCallToAction = (newWidth, newHeight) => { this.setState({ callToActionWidth: newWidth }); }; this.state = { fadingOut: false }; } fadeOut() { this.fadeOutPromise && this.fadeOutPromise.cancel(); const basePromise = new Promise(resolve => { this.setState({ fadingOut: true }); setTimeout(() => { resolve(); }, 500); }); this.fadeOutPromise = makeCancelable(basePromise); return this.fadeOutPromise; } render() { const { message, callToAction, className } = this.props; const { callToActionWidth, fadingOut } = this.state; // Set up class names based on layout const renderAsSingleLine = !callToAction || !callToActionWidth || callToActionWidth <= 120; const flexLayoutClass = renderAsSingleLine ? "one-line flex-row" : "multi-line flex-column"; const messageClass = renderAsSingleLine ? "flex-grow" : undefined; const fadeOutClass = fadingOut ? "fade-out" : undefined; return (React.createElement(Callout, { className: css(className, "bolt-toast no-events"), contentClassName: css("bolt-toast-content", flexLayoutClass, fadeOutClass), contentJustification: ContentJustification.Center, contentLocation: ContentLocation.End }, React.createElement("span", { className: css("bolt-toast-message flex-shrink", messageClass), id: getSafeId("toast-message"), role: "alert" }, message), callToAction && (React.createElement(React.Fragment, null, React.createElement("span", { className: "bolt-toast-separator flex-noshrink" }), React.createElement(Measure, { onMeasure: this.onMeasureCallToAction }, React.createElement("div", { className: "bolt-toast-call-to-action-container" }, React.createElement(Button, { ariaDescribedBy: "toast-message", className: "bolt-toast-call-to-action flex-noshrink", ref: this.callToActionRef, subtle: true, onClick: this.onCallToActionClick }, callToAction))))))); } componentDidMount() { document.addEventListener("keydown", this.onKeyboardShortcut); } componentWillUnmount() { this.fadeOutPromise && this.fadeOutPromise.cancel(); document.removeEventListener("keydown", this.onKeyboardShortcut); } }