@ysmood/material-ui
Version:
Material Design UI components built with React
141 lines (114 loc) • 3.25 kB
JSX
var React = require('react');
var StylePropable = require('./mixins/style-propable');
var AutoPrefix = require('./styles/auto-prefix');
var EnhancedTextarea = React.createClass({
mixins: [StylePropable],
propTypes: {
onChange: React.PropTypes.func,
onHeightChange: React.PropTypes.func,
textareaStyle: React.PropTypes.object,
rows: React.PropTypes.number
},
getDefaultProps: function() {
return {
rows: 1
};
},
getInitialState: function() {
return {
height: this.props.rows * 24
};
},
componentDidMount: function() {
this._syncHeightWithShadow();
},
getStyles: function() {
var styles = {
root: {
width: '100%',
resize: 'none',
overflow: 'hidden',
font: 'inherit',
padding: 0,
}
};
return styles;
},
render: function() {
var {
onChange,
onHeightChange,
rows,
style,
textareaStyle,
valueLink,
...other
} = this.props;
var styles = this.getStyles().root;
var textAreaStyles = {
width: '100%',
resize: 'none',
overflow: 'hidden',
font: 'inherit',
padding: 0,
};
var inputStyles = this.mergeAndPrefix(styles,{
height: this.state.height + 'px',
});
inputStyles = this.mergeAndPrefix(inputStyles, textareaStyle);
// Overflow also needed to here to remove the extra row
// added to textareas in Firefox.
var shadowStyles = this.mergeAndPrefix(textAreaStyles, {
position: 'absolute',
opacity: 0
});
if (this.props.hasOwnProperty('valueLink')) other.value = this.props.valueLink.value;
if (this.props.disabled) style.cursor = 'default';
return (
<div style={this.props.style}>
<textarea
ref="shadow"
style={AutoPrefix.all(shadowStyles)}
tabIndex="-1"
rows={this.props.rows}
defaultValue={this.props.defaultValue}
readOnly={true}
value={this.props.value}
valueLink={this.props.valueLink} />
<textarea
{...other}
ref="input"
rows={this.props.rows}
style={AutoPrefix.all(inputStyles)}
onChange={this._handleChange} />
</div>
);
},
getInputNode: function() {
return React.findDOMNode(this.refs.input);
},
_syncHeightWithShadow: function(newValue, e) {
var shadow = React.findDOMNode(this.refs.shadow);
var currentHeight = this.state.height;
var newHeight;
if (newValue !== undefined) shadow.value = newValue;
newHeight = shadow.scrollHeight;
if (currentHeight !== newHeight) {
this.setState({height: newHeight});
if (this.props.onHeightChange) this.props.onHeightChange(e, newHeight);
}
},
_handleChange: function(e) {
this._syncHeightWithShadow(e.target.value);
if (this.props.hasOwnProperty('valueLink')) {
this.props.valueLink.requestChange(e.target.value);
}
if (this.props.onChange) this.props.onChange(e);
},
componentWillReceiveProps: function(nextProps) {
if (nextProps.value != this.props.value) {
this._syncHeightWithShadow(nextProps.value);
}
}
});
module.exports = EnhancedTextarea;