UNPKG

3.5 kBJavaScriptView Raw
1/**
2 * External dependencies
3 */
4import { View } from 'react-native';
5
6/**
7 * WordPress dependencies
8 */
9import { __ } from '@wordpress/i18n';
10import { Component } from '@wordpress/element';
11import { createBlock } from '@wordpress/blocks';
12import { RichText } from '@wordpress/block-editor';
13
14/**
15 * Internal dependencies
16 */
17import styles from './style.scss';
18
19const name = 'core/paragraph';
20
21class ParagraphEdit extends Component {
22 constructor( props ) {
23 super( props );
24 this.splitBlock = this.splitBlock.bind( this );
25 this.onReplace = this.onReplace.bind( this );
26
27 this.state = {
28 aztecHeight: 0,
29 };
30 }
31
32 /**
33 * Split handler for RichText value, namely when content is pasted or the
34 * user presses the Enter key.
35 *
36 * @param {?Array} before Optional before value, to be used as content
37 * in place of what exists currently for the
38 * block. If undefined, the block is deleted.
39 * @param {?Array} after Optional after value, to be appended in a new
40 * paragraph block to the set of blocks passed
41 * as spread.
42 * @param {...WPBlock} blocks Optional blocks inserted between the before
43 * and after value blocks.
44 */
45 splitBlock( before, after, ...blocks ) {
46 const {
47 attributes,
48 insertBlocksAfter,
49 setAttributes,
50 onReplace,
51 } = this.props;
52
53 if ( after !== null ) {
54 // Append "After" content as a new paragraph block to the end of
55 // any other blocks being inserted after the current paragraph.
56 const newBlock = createBlock( name, { content: after } );
57 blocks.push( newBlock );
58 }
59
60 if ( blocks.length && insertBlocksAfter ) {
61 insertBlocksAfter( blocks );
62 }
63
64 const { content } = attributes;
65 if ( before === null ) {
66 onReplace( [] );
67 } else if ( content !== before ) {
68 // Only update content if it has in-fact changed. In case that user
69 // has created a new paragraph at end of an existing one, the value
70 // of before will be strictly equal to the current content.
71 setAttributes( { content: before } );
72 }
73 }
74
75 onReplace( blocks ) {
76 const { attributes, onReplace } = this.props;
77 onReplace( blocks.map( ( block, index ) => (
78 index === 0 && block.name === name ?
79 { ...block,
80 attributes: {
81 ...attributes,
82 ...block.attributes,
83 },
84 } :
85 block
86 ) ) );
87 }
88
89 render() {
90 const {
91 attributes,
92 setAttributes,
93 mergeBlocks,
94 style,
95 } = this.props;
96
97 const {
98 placeholder,
99 content,
100 } = attributes;
101
102 const minHeight = styles.blockText.minHeight;
103
104 return (
105 <View>
106 <RichText
107 tagName="p"
108 value={ content }
109 isSelected={ this.props.isSelected }
110 onFocus={ this.props.onFocus } // always assign onFocus as a props
111 onBlur={ this.props.onBlur } // always assign onBlur as a props
112 onCaretVerticalPositionChange={ this.props.onCaretVerticalPositionChange }
113 style={ {
114 ...style,
115 minHeight: Math.max( minHeight, this.state.aztecHeight ),
116 } }
117 onChange={ ( nextContent ) => {
118 setAttributes( {
119 content: nextContent,
120 } );
121 } }
122 onSplit={ this.splitBlock }
123 onMerge={ mergeBlocks }
124 onReplace={ this.onReplace }
125 onContentSizeChange={ ( event ) => {
126 this.setState( { aztecHeight: event.aztecHeight } );
127 } }
128 placeholder={ placeholder || __( 'Start writing…' ) }
129 />
130 </View>
131 );
132 }
133}
134
135export default ParagraphEdit;