ui-kit
Version:
user interface kit
139 lines (120 loc) • 4.23 kB
text/jade
:doc
UIGrowingInput
{Boolean} readonly
{Boolean} required
{Boolean} shouldAutoFocus
{Function} onBlur
{Function} onChange
{Function} onFocus
{Function} onKeydown
{Object} template
{Number} maxLength
{Number} minLength
{String} [ariaLabel] label for accessibility
{String} className
{String} defaultValue
{String} type
{String} valueKey
import * as debounce from 'debounce'
// import * as ReactDOM from 'react-dom'
import {KEY_NAMES} from '../../utils/keybinding.js'
import './index.ess'
const VIRTUAL_INPUT_STYLE = {position: 'absolute', left: '10000px', right: '10000px'}
var.
componentProps = {
className: props.className,
defaultValue: props.defaultValue,
maxLength: props.maxLength,
minLength: props.minLength,
onBlur: this.onBlur,
onFocus: this.onFocus,
onChange: this.onChange,
onKeyDown: this.onKeyDown,
placeholder: props.placeholder,
readOnly: props.readOnly,
required: props.required,
style: props.style,
tabIndex: props.tabIndex,
type: 'textarea',
'aria-label': props['aria-label']
}
var useAutoId = !!props.label && !props.id
var id = useAutoId ? this.getNextUid('InputComponent') : props.id
var labelFor = useAutoId ? this.getNextUid('InputComponent') : props.id
var value = (state.value || state.value === '' ) ? state.value : props.defaultValue
textarea(id=id rows='1' autoFocus=props.shouldAutoFocus value=value)&props(componentProps)
-this.recalculateSize();
:module
export function getDefaultProps () {
return {
submitOnEnter: true,
valueKey: 'value'
};
}
export function componentWillMount () {
this.recalculateSize = debounce(this.recalculateSize, 100);
this.submitTemplate = debounce(this.submitTemplate, 500);
}
export function componentWillReceiveProps (props) {
if (props.defaultValue !== this.props.defaultValue && !this.state.hasFocus) this.setState({value: props.defaultValue});
if (props.shouldAutoFocus && props.shouldAutoFocus !== this.props.shouldAutoFocus) this.getRootNode().focus();
return true;
}
export function getRootNode () {
// return this.getDOMNode ? this.getDOMNode() : ReactDOM.findDOMNode(this);
return this.getDOMNode();
}
export function onBlur (ev) {
this.setState({hasFocus: false});
if (this.props.onBlur) this.props.onBlur.apply(this, arguments);
}
export function onFocus (ev) {
this.setState({hasFocus: true});
if (this.props.onFocus) this.props.onFocus.apply(this, arguments);
}
export function onChange (ev) {
var value = ev.target.value;
this.setState({value: value});
if (this.props.onChange) this.props.onChange.apply(null, arguments);
this.submitTemplate();
}
export function recalculateSize () {
if (!this.isMounted()) return;
var input = this.getRootNode();
var newHeight = this.getVirtualInputHeight(input);
if (newHeight !== Number(input.style.height.split('px')[0]))
input.style.height = [newHeight, 'px'].join('');
}
export function getVirtualInputHeight (input) {
var vInput = input.cloneNode();
vInput.style.width = input.clientWidth + 'px';
vInput.value = input.value;
for (var key in VIRTUAL_INPUT_STYLE) {
vInput.style[key] = VIRTUAL_INPUT_STYLE[key];
}
input.parentElement.appendChild(vInput);
vInput.style.height = '';
var height = vInput.scrollHeight;
input.parentElement.removeChild(vInput);
return height;
}
export function onKeyDown (evt) {
if (this.props.onKeyDown) this.props.onKeyDown.apply(null, arguments);
if (this.props.submitOnEnter === true && evt.keyCode === KEY_NAMES.enter) {
evt.preventDefault();
this.submitTemplate();
}
}
export function submitTemplate () {
if (!this.props.template) return;
var el = this.getRootNode();
var value = el.value.trim();
this.context.forms.create(this.props.template)
.set({[this.props.valueKey]: value})
.submit((err, res) => {
if (err) {
if (this.props.onError) this.props.onError(err);
console.warn(err);
}
});
}