@@ -46,37 +46,69 @@ export default class EditorWrapper extends React.Component {
46
46
this . customPlugin = createCustomPlugin ( {
47
47
editor : this ,
48
48
} ) ;
49
+
50
+ this . onBeforeInput = this . onBeforeInput . bind ( this ) ;
51
+ this . onPasteText = this . onPasteText . bind ( this ) ;
49
52
}
50
53
51
54
componentDidMount ( ) {
52
55
const { connector, initialContent } = this . props ;
53
56
connector . addEditor ( this ) ;
54
- if ( initialContent ) {
55
- let editorState = convertFromHTML ( initialContent ) ;
56
- editorState = ContentState . createFromBlockArray (
57
- editorState . contentBlocks ,
58
- editorState . entityMap ,
59
- ) ;
60
- editorState = EditorState . createWithContent ( editorState ) ;
61
- this . initialContent = editorState . getCurrentContent ( ) ;
62
- setImmediate ( ( ) => this . setState ( { editor : editorState } ) ) ;
63
- }
57
+ this . setInitialContent ( initialContent ) ;
64
58
}
65
59
66
- componentWillReceiveProps ( { connector, id } ) {
67
- const { connector : prevConnector } = this . props ;
60
+ componentWillReceiveProps ( { connector, id, initialContent } ) {
61
+ const { connector : prevConnector , initialContent : prevInitialContent } = this . props ;
68
62
this . id = id ;
69
63
if ( connector !== prevConnector ) {
70
64
if ( prevConnector ) prevConnector . removeEditor ( this ) ;
71
65
if ( connector ) connector . addEditor ( this ) ;
72
66
}
67
+ if ( initialContent !== prevInitialContent ) {
68
+ this . setInitialContent ( initialContent ) ;
69
+ }
73
70
}
74
71
75
72
componentWillUnmount ( ) {
76
73
const { connector } = this . props ;
77
74
connector . removeEditor ( this ) ;
78
75
}
79
76
77
+ onBeforeInput ( ) { // eslint-disable-line consistent-return
78
+ const { maxLength } = this . props ;
79
+ const { editor : editorState } = this . state ;
80
+ if ( maxLength !== - 1 && maxLength <= editorState . getCurrentContent ( ) . getPlainText ( '' ) . length ) {
81
+ return 'handled' ;
82
+ }
83
+ }
84
+
85
+ onPasteText ( text ) { // eslint-disable-line consistent-return
86
+ const { maxLength } = this . props ;
87
+ const { editor : editorState } = this . state ;
88
+ if ( maxLength !== - 1 && maxLength <= text . length + editorState . getCurrentContent ( ) . getPlainText ( '' ) . length ) {
89
+ return 'handled' ;
90
+ }
91
+ }
92
+
93
+ setInitialContent ( content ) {
94
+ if ( content ) {
95
+ let editorState = convertFromHTML ( content ) ;
96
+ if ( editorState . contentBlocks ) {
97
+ editorState = ContentState . createFromBlockArray (
98
+ editorState . contentBlocks ,
99
+ editorState . entityMap ,
100
+ ) ;
101
+ editorState = EditorState . createWithContent ( editorState ) ;
102
+ this . initialContent = editorState . getCurrentContent ( ) ;
103
+ setImmediate ( ( ) => this . setState ( { editor : editorState } ) ) ;
104
+ }
105
+ } else {
106
+ let { editor : editorState } = this . state ;
107
+ editorState = EditorState . push ( editorState , ContentState . createFromText ( '' ) ) ;
108
+ this . setState ( { editor : editorState } ) ;
109
+ }
110
+ }
111
+
80
112
getHtml ( ) {
81
113
const { editor } = this . state ;
82
114
return editorStateToHTML ( editor . getCurrentContent ( ) ) ;
@@ -98,10 +130,9 @@ export default class EditorWrapper extends React.Component {
98
130
* @param {String } type The new block style
99
131
*/
100
132
applyBlockStyle ( type ) {
101
- const { editor } = this . state ;
102
- let editorState = editor ;
133
+ let { editor : editorState } = this . state ;
103
134
editorState = RichUtils . toggleBlockType ( editorState , type ) ;
104
- this . setState ( { editorState } ) ; // eslint-disable-line
135
+ this . setState ( { editor : editorState } ) ; // eslint-disable-line
105
136
}
106
137
107
138
/**
@@ -231,13 +262,16 @@ export default class EditorWrapper extends React.Component {
231
262
}
232
263
233
264
render ( ) {
234
- const { connector, theme } = this . props ;
265
+ const { connector, theme, placeholder } = this . props ;
235
266
236
267
const st = this . state ;
237
268
238
269
let containerStyles = style . container ;
239
270
if ( st . editor . getSelection ( ) . getHasFocus ( ) ) {
240
- containerStyles += ` ${ style . focused } ` ;
271
+ containerStyles += ` ${ style . focused } is-focused` ;
272
+ }
273
+ if ( st . editor . getCurrentContent ( ) . hasText ( ) || / < o l > | < u l > / . test ( this . getHtml ( ) ) ) {
274
+ containerStyles += ' has-user-input' ;
241
275
}
242
276
if ( theme . container ) {
243
277
containerStyles += ` ${ theme . container } ` ;
@@ -253,6 +287,7 @@ export default class EditorWrapper extends React.Component {
253
287
tabIndex = { 0 }
254
288
>
255
289
< Editor
290
+ placeholder = { placeholder }
256
291
editorState = { st . editor }
257
292
handleKeyCommand = { ( command , state ) => {
258
293
const editorState = RichUtils . handleKeyCommand ( state , command ) ;
@@ -283,6 +318,8 @@ export default class EditorWrapper extends React.Component {
283
318
] }
284
319
ref = { ( node ) => { this . node = node ; } }
285
320
spellCheck
321
+ handleBeforeInput = { this . onBeforeInput }
322
+ handlePastedText = { this . onPasteText }
286
323
/>
287
324
</ div >
288
325
) ;
@@ -292,13 +329,17 @@ export default class EditorWrapper extends React.Component {
292
329
EditorWrapper . defaultProps = {
293
330
connector : new Connector ( ) ,
294
331
id : null ,
295
- initialContent : null ,
332
+ initialContent : '' ,
296
333
theme : { } ,
334
+ placeholder : '' ,
335
+ maxLength : - 1 ,
297
336
} ;
298
337
299
338
EditorWrapper . propTypes = {
300
339
connector : PT . instanceOf ( Connector ) ,
301
340
id : PT . string ,
302
341
initialContent : PT . string ,
303
342
theme : PT . shape ( ) ,
343
+ placeholder : PT . string ,
344
+ maxLength : PT . number ,
304
345
} ;
0 commit comments