azure-devops-ui
Version:
React components for building web UI in Azure DevOps
65 lines (64 loc) • 3.53 kB
JavaScript
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);
}
}