import * as React from 'react' ; export interface StateProps { realtime : any ; realtimeModel : any ; } export interface DispatchProps { onDirty : ( realtime : any , text : string ) => void ; } interface Props extends StateProps , DispatchProps { } class RealtimeTextArea extends React . Component < Props , { } > { public silentChange : boolean ; public ref : any ; public getValue ( ) { if ( this . props . realtime ) { return this . props . realtime . getText ( ) ; } return '' ; } public setValue ( value ) { if ( this . props . realtime ) { this . props . realtimeModel . beginCompoundOperation ( '' , false ) ; this . props . realtime . setValue ( value ) ; this . props . realtimeModel . endCompoundOperation ( ) ; } } public onRef ( ref ) { this . ref = ref ; if ( ! this . ref ) { return ; } if ( this . props . realtime ) { this . ref . value = this . props . realtime . getText ( ) ; } this . componentWillReceiveProps ( this . props ) ; } public onTextInserted ( event ) { if ( event . isLocal ) { return ; } this . silentChange = true ; this . ref . value = this . ref . value . substr ( 0 , event . index ) + event . text + this . ref . value . substr ( event . index ) ; this . silentChange = false ; } public onTextDeleted ( event ) { if ( event . isLocal ) { return ; } this . silentChange = true ; this . ref . value = this . ref . value . substr ( 0 , event . index ) + this . ref . value . substr ( event . index + event . text . length ) ; this . silentChange = false ; } public componentWillReceiveProps ( newProps ) { if ( this . props . realtime ) { this . props . realtime . removeAllEventListeners ( ) ; } } public onChange ( e ) { if ( this . silentChange ) { return ; } this . props . onDirty ( this . props . realtime , e . target . value ) ; this . ref . value = this . props . realtime . getText ( ) ; } public render ( ) { return ( < textarea id = "notesArea" ref = { ( ref ) => this . onRef ( ref ) } onChange = { ( e ) => this . onChange ( e ) } />); } } const NotesPanel = ( props ) : JSX . Element => { return ( < div className = "console" > < div className = "interactive" > < RealtimeTextArea realtime = { props . realtime } realtimeModel = { props . realtimeModel } onDirty = { props . onDirty } / > < /div> < /div>); } ; export default NotesPanel ;