TopSiteFormInput.jsx (3186B)
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 React from "react"; 6 7 export class TopSiteFormInput extends React.PureComponent { 8 constructor(props) { 9 super(props); 10 this.state = { validationError: this.props.validationError }; 11 this.onChange = this.onChange.bind(this); 12 this.onMount = this.onMount.bind(this); 13 this.onClearIconPress = this.onClearIconPress.bind(this); 14 } 15 16 componentWillReceiveProps(nextProps) { 17 if (nextProps.shouldFocus && !this.props.shouldFocus) { 18 this.input.focus(); 19 } 20 if (nextProps.validationError && !this.props.validationError) { 21 this.setState({ validationError: true }); 22 } 23 // If the component is in an error state but the value was cleared by the parent 24 if (this.state.validationError && !nextProps.value) { 25 this.setState({ validationError: false }); 26 } 27 } 28 29 onClearIconPress(event) { 30 // If there is input in the URL or custom image URL fields, 31 // and we hit 'enter' while tabbed over the clear icon, 32 // we should execute the function to clear the field. 33 if (event.key === "Enter") { 34 this.props.onClear(); 35 } 36 } 37 38 onChange(ev) { 39 if (this.state.validationError) { 40 this.setState({ validationError: false }); 41 } 42 this.props.onChange(ev); 43 } 44 45 onMount(input) { 46 this.input = input; 47 } 48 49 renderLoadingOrCloseButton() { 50 const showClearButton = this.props.value && this.props.onClear; 51 52 if (this.props.loading) { 53 return ( 54 <div className="loading-container"> 55 <div className="loading-animation" /> 56 </div> 57 ); 58 } else if (showClearButton) { 59 return ( 60 <button 61 type="button" 62 className="icon icon-clear-input icon-button-style" 63 onClick={this.props.onClear} 64 onKeyPress={this.onClearIconPress} 65 /> 66 ); 67 } 68 return null; 69 } 70 71 render() { 72 const { typeUrl } = this.props; 73 const { validationError } = this.state; 74 75 return ( 76 <label> 77 <span data-l10n-id={this.props.titleId} /> 78 <div 79 className={`field ${typeUrl ? "url" : ""}${ 80 validationError ? " invalid" : "" 81 }`} 82 > 83 <input 84 type="text" 85 value={this.props.value} 86 ref={this.onMount} 87 onChange={this.onChange} 88 data-l10n-id={this.props.placeholderId} 89 // Set focus on error if the url field is valid or when the input is first rendered and is empty 90 // eslint-disable-next-line jsx-a11y/no-autofocus 91 autoFocus={this.props.autoFocusOnOpen} 92 disabled={this.props.loading} 93 /> 94 {this.renderLoadingOrCloseButton()} 95 {validationError && ( 96 <aside 97 className="error-tooltip" 98 data-l10n-id={this.props.errorMessageId} 99 /> 100 )} 101 </div> 102 </label> 103 ); 104 } 105 } 106 107 TopSiteFormInput.defaultProps = { 108 showClearButton: false, 109 value: "", 110 validationError: false, 111 };