import React, { Component } from "react"; import PropTypes from "prop-types"; import classnames from "classnames"; import { noop, pick } from "lodash"; import { stringToClipboard } from "utilities/copy_text"; import FormField from "components/forms/FormField"; import Button from "components/buttons/Button"; import Icon from "components/Icon"; const baseClass = "input-field"; class InputField extends Component { static propTypes = { autofocus: PropTypes.bool, /** readOnly displays a non-editable field */ readOnly: PropTypes.bool, /** disabled displays a greyed out non-editable field */ disabled: PropTypes.bool, error: PropTypes.string, inputClassName: PropTypes.string, // eslint-disable-line react/forbid-prop-types inputWrapperClass: PropTypes.string, inputOptions: PropTypes.object, // eslint-disable-line react/forbid-prop-types name: PropTypes.string, onChange: PropTypes.func, onBlur: PropTypes.func, onFocus: PropTypes.func, placeholder: PropTypes.string, type: PropTypes.string, blockAutoComplete: PropTypes.bool, value: PropTypes.oneOfType([ PropTypes.bool, PropTypes.string, PropTypes.number, ]).isRequired, /** Returns both name and value */ parseTarget: PropTypes.bool, tooltip: PropTypes.oneOfType([PropTypes.string, PropTypes.object]), labelTooltipPosition: PropTypes.string, helpText: PropTypes.oneOfType([ PropTypes.string, PropTypes.arrayOf(PropTypes.string), PropTypes.object, ]), /** Use in conjunction with type "password" and enableCopy to see eye icon to view */ enableShowSecret: PropTypes.bool, enableCopy: PropTypes.bool, ignore1password: PropTypes.bool, // Accepts string or number for HTML compatibility, (e.g., step="0.1", step={0.1}) /** Only effective on input type number */ step: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), /** Only effective on input type number */ min: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), /** Only effective on input type number */ max: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), }; static defaultProps = { autofocus: false, inputWrapperClass: "", inputOptions: {}, label: null, labelClassName: "", onFocus: noop, onBlur: noop, type: "text", blockAutoComplete: false, value: "", parseTarget: false, tooltip: "", labelTooltipPosition: undefined, helpText: "", enableCopy: false, enableShowSecret: false, ignore1password: false, step: undefined, min: undefined, max: undefined, }; constructor() { super(); this.state = { copied: false, }; } componentDidMount() { const { autofocus } = this.props; const { input } = this; if (autofocus) { input.focus(); } return false; } onInputChange = (evt) => { evt.preventDefault(); const { value, name } = evt.target; const { onChange, parseTarget } = this.props; if (parseTarget) { // Returns both name and value return onChange({ value, name }); } return onChange(value); }; onToggleSecret = (evt) => { evt.preventDefault(); this.setState({ showSecret: !this.state.showSecret }); return false; }; onClickCopy = (e) => { e.preventDefault(); stringToClipboard(this.props.value).then(() => { this.setState({ copied: true }); setTimeout(() => { this.setState({ copied: false }); }, 2000); }); }; renderShowSecretButton = () => { const { onToggleSecret } = this; return ( ); }; renderCopyButton = () => { const { onClickCopy } = this; const copyButtonValue = ; const wrapperClasses = classnames(`${baseClass}__copy-wrapper`, { [`${baseClass}__copy-wrapper__text-area`]: this.props.type === "textarea", }); const copiedConfirmationClasses = classnames( `${baseClass}__copied-confirmation` ); return (
{this.state.copied && ( Copied! )} {this.props.enableShowSecret && this.renderShowSecretButton()}
); }; render() { const { readOnly, disabled, error, inputClassName, inputOptions, inputWrapperClass, name, onFocus, onBlur, placeholder, type, blockAutoComplete, value, ignore1password, enableCopy, enableShowSecret, step, min, max, } = this.props; const { onInputChange } = this; const shouldShowPasswordClass = type === "password" && !this.state.showSecret; const inputClasses = classnames(baseClass, inputClassName, { [`${baseClass}--password`]: shouldShowPasswordClass, [`${baseClass}--read-only`]: readOnly || disabled, [`${baseClass}--disabled`]: disabled, [`${baseClass}--error`]: error, [`${baseClass}__textarea`]: type === "textarea", }); const inputWrapperClasses = classnames(inputWrapperClass, { [`input-field--read-only`]: readOnly || disabled, [`input-field--disabled`]: disabled, }); const formFieldProps = pick(this.props, [ "helpText", "label", "error", "name", "tooltip", "labelTooltipPosition", ]); const inputContainerClasses = classnames(`${baseClass}__input-container`, { "copy-enabled": enableCopy, }); if (type === "textarea") { return (