UNPKG

optimizely-oui

Version:

Optimizely's Component Library.

185 lines (173 loc) 5.61 kB
import React from "react"; import Label from "../Label"; import classNames from "classnames"; import PropTypes from "prop-types"; /** * Generates a `textarea` element. * @param {Object} props - Properties passed to component * @returns {ReactElement} */ class Textarea extends React.Component { blur() { if (this._textarea) { this._textarea.blur(); } } renderTextarea({ className, defaultValue, displayError, focus, isDisabled, isOptional, isReadOnly, isRequired, label, maxLength, note, numRows, onBlur, onChange, onFocus, onInput, onKeyDown, placeholder, testSection, value, ...props }) { const classes = classNames({ "oui-textarea": true }, { "oui-form-bad-news": displayError }, className); return ( /* eslint-disable react/jsx-no-bind */ <textarea data-oui-component={true} className={classes} ref={c => { this._textarea = c; }} value={value} defaultValue={defaultValue} placeholder={placeholder} required={isRequired} readOnly={isReadOnly} disabled={isDisabled} {...(typeof maxLength === "undefined" ? {} : { maxLength })} maxLength={maxLength} rows={numRows} onInput={onInput} onChange={onChange} onBlur={onBlur} onKeyDown={onKeyDown} onFocus={onFocus} autoFocus={focus} data-test-section={testSection} {...props} /> /* eslint-enable react/jsx-no-bind */ ); } renderNote({ note, testSection }) { return ( <div className="oui-form-note" data-test-section={testSection && testSection + "-note"}> {note} </div> ); } render() { const { displayError, isOptional, isRequired, label, note, testSection, } = this.props; if (label) { return ( <div data-oui-component={true} className={classNames({ "oui-form-bad-news": displayError })}> <Label testSection={testSection && testSection + "-label"}> <div className="oui-label"> {label} {isOptional && <span className="oui-label__optional">(Optional)</span>} {isRequired && <span className="oui-label--required"></span>} </div> {this.renderTextarea(this.props)} </Label> {note && this.renderNote(this.props)} </div> ); } if (note) { return [this.renderTextarea(this.props), this.renderNote(this.props)]; } return this.renderTextarea(this.props); } } Textarea.propTypes = { /** The default value of the textarea used on initial render */ defaultValue: PropTypes.string, /** Shows error styling if true */ displayError: PropTypes.bool, /** Auto focus the Textaraea if true */ focus: PropTypes.bool, /** Prevents textarea from being modified and appears disabled */ isDisabled: PropTypes.bool, /** Adds an optional label if there is a label provided * @param {Object} props Object of props * @returns {Error} Error or null */ isOptional: function verifyIsOptionalProp(props) { if (props.isOptional && !props.label) { return new Error("Must include a value for the label prop to use the isOptional prop"); } if (props.isOptional && props.isRequired) { return new Error("Textarea cannot be both optional and required, please pick one "); } return null; }, /** Prevents textarea from being modified but doesn't appear disabled */ isReadOnly: PropTypes.bool, /** Prevents textarea from being submitted without value */ isRequired: PropTypes.bool, /** Text that describes the textarea */ label: PropTypes.string, /** * Max length of the input value */ maxLength: PropTypes.number, /** Form note for the input */ note: PropTypes.string, /** Number of rows to fit in the textarea */ numRows: PropTypes.number, /** Function that fires when the textarea loses focus. It fires regardless of whether the value has changed. */ onBlur: PropTypes.func, /** Function that fires when the textarea loses focus after the value changes */ onChange: PropTypes.func, /** Function that fires when the textarea gains focus */ onFocus: PropTypes.func, /** Function that fires the the textarea value changes */ onInput: PropTypes.func, /** Function that fires when a key is pressed down */ onKeyDown: PropTypes.func, /** Textarea placeholder text */ placeholder: PropTypes.string, /** Hook for automated JavaScript tests */ testSection: PropTypes.string, /** Text within the textarea */ value: PropTypes.string, }; Textarea.defaultProps = { displayError: false, focus: false, label: null, note: null, numRows: 3, isOptional: false, }; export default Textarea;