docs: function TextInput( options = {} ) {
  	Element.call( this , options ) ;
  
  	// TextBufffer needs computed attr, not object one
  	this.textAttr = options.textAttr || { bgColor: 'blue' } ;
  	this.emptyAttr = options.emptyAttr || { bgColor: 'blue' } ;
  
  	this.hidden = options.hidden ;
  
  	this.labelFocusAttr = options.labelFocusAttr || { bold: true } ;
  	this.labelBlurAttr = options.labelBlurAttr || { dim: true } ;
  
  	if ( options.keyBindings ) { this.keyBindings = options.keyBindings ; }
  
  	if ( options.editableTextBoxKeyBindings ) { this.editableTextBoxKeyBindings = options.editableTextBoxKeyBindings ; }
  	else if ( options.allowNewLine ) { this.editableTextBoxKeyBindings = this.multiLineEditableTextBoxKeyBindings ; }
  
  	if ( this.label ) {
  		this.labelText = new Text( {
  			parent: this ,
  			content: this.label ,
  			x: this.outputX ,
  			y: this.outputY ,
  			height: 1 ,
  			attr: this.labelBlurAttr ,
  			leftPadding: this.labelBlurLeftPadding ,
  			rightPadding: this.labelBlurRightPadding ,
  			noDraw: true
  		} ) ;
  	}
  
  	this.editableTextBox = new EditableTextBox( {
  		parent: this ,
  		content: this.value || this.content ,
  		x: this.outputX + ( this.labelText ? this.labelText.outputWidth : 0 ) ,
  		y: this.outputY ,
  		width: this.outputWidth - ( this.labelText ? this.labelText.outputWidth : 0 ) ,
  		height: this.outputHeight ,
  		hidden: this.hidden ,
  		textAttr: this.textAttr ,
  		emptyAttr: this.emptyAttr ,
  		keyBindings: this.editableTextBoxKeyBindings ,
  		noDraw: true
  	} ) ;
  
  	this.updateStatus() ;
  
  	this.onKey = this.onKey.bind( this ) ;
  	this.onFocus = this.onFocus.bind( this ) ;
  	this.onClick = this.onClick.bind( this ) ;
  
  	this.on( 'key' , this.onKey ) ;
  	this.on( 'focus' , this.onFocus ) ;
  	this.on( 'click' , this.onClick ) ;
  
  	// Only draw if we are not a superclass of the object
  	if ( this.elementType === 'TextInput' && ! options.noDraw ) { this.draw() ; }
  }