ConfirmDialog.jsx (3681B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this file, 3 * You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 import { actionCreators as ac, actionTypes } from "common/Actions.mjs"; 6 import { connect } from "react-redux"; 7 import React from "react"; 8 9 /** 10 * ConfirmDialog component. 11 * One primary action button, one cancel button. 12 * 13 * Content displayed is controlled by `data` prop the component receives. 14 * Example: 15 * data: { 16 * // Any sort of data needed to be passed around by actions. 17 * payload: site.url, 18 * // Primary button AlsoToMain action. 19 * action: "DELETE_HISTORY_URL", 20 * // Primary button USerEvent action. 21 * userEvent: "DELETE", 22 * // Array of locale ids to display. 23 * message_body: ["confirm_history_delete_p1", "confirm_history_delete_notice_p2"], 24 * // Text for primary button. 25 * confirm_button_string_id: "menu_action_delete" 26 * }, 27 */ 28 export class _ConfirmDialog extends React.PureComponent { 29 constructor(props) { 30 super(props); 31 this._handleCancelBtn = this._handleCancelBtn.bind(this); 32 this._handleConfirmBtn = this._handleConfirmBtn.bind(this); 33 this.dialogRef = React.createRef(); 34 } 35 36 componentDidUpdate() { 37 const dialogElement = this.dialogRef.current; 38 if (!dialogElement) { 39 return; 40 } 41 42 // Open dialog when visible becomes true 43 if (this.props.visible && !dialogElement.open) { 44 dialogElement.showModal(); 45 } 46 // Close dialog when visible becomes false 47 else if (!this.props.visible && dialogElement.open) { 48 dialogElement.close(); 49 } 50 } 51 52 _handleCancelBtn() { 53 this.props.dispatch({ type: actionTypes.DIALOG_CANCEL }); 54 this.props.dispatch( 55 ac.UserEvent({ 56 event: actionTypes.DIALOG_CANCEL, 57 source: this.props.data.eventSource, 58 }) 59 ); 60 } 61 62 _handleConfirmBtn() { 63 this.props.data.onConfirm.forEach(this.props.dispatch); 64 } 65 66 _renderModalMessage() { 67 const message_body = this.props.data.body_string_id; 68 69 if (!message_body) { 70 return null; 71 } 72 73 return ( 74 <span> 75 {message_body.map(msg => ( 76 <p key={msg} data-l10n-id={msg} /> 77 ))} 78 </span> 79 ); 80 } 81 82 render() { 83 return ( 84 <dialog 85 ref={this.dialogRef} 86 className="confirmation-dialog" 87 onClick={e => { 88 // Close modal when clicking on the backdrop pseudo element (the background of the modal) 89 if (e.target === this.dialogRef.current) { 90 this._handleCancelBtn(); 91 } 92 }} 93 > 94 <div className="modal"> 95 <section className="modal-message"> 96 {this.props.data.icon && ( 97 <span 98 className={`icon icon-spacer icon-${this.props.data.icon}`} 99 /> 100 )} 101 {this._renderModalMessage()} 102 </section> 103 <section className="button-group"> 104 <moz-button-group> 105 <moz-button 106 onClick={this._handleCancelBtn} 107 data-l10n-id={this.props.data.cancel_button_string_id} 108 ></moz-button> 109 <moz-button 110 type="primary" 111 onClick={this._handleConfirmBtn} 112 data-l10n-id={this.props.data.confirm_button_string_id} 113 data-l10n-args={JSON.stringify( 114 this.props.data.confirm_button_string_args 115 )} 116 ></moz-button> 117 </moz-button-group> 118 </section> 119 </div> 120 </dialog> 121 ); 122 } 123 } 124 125 export const ConfirmDialog = connect(state => state.Dialog)(_ConfirmDialog);