-
Notifications
You must be signed in to change notification settings - Fork 4.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Introduces RichText component for mobile and ports Para block for mob…
…ile (#8231) * Introduce RichText component for mobile, and port the Paragraph block by using the newly introduced RichText component. * Fix lint * Use an edit file to share more common code with the main Paragraph web code. * Fix lint * Remove log calls * Revert renaming of custom-class-name.native.js → custom-class-name-native.js and relevant import statement. * Cleaning the code / Refactoring by "nativizing" `utils.js` (& `index.js`) in raw-handling * Remove any extra P. * Replace <p> by <br> * The RichText mobile component now returns plain HTML, and the transformation from HTML to React is made in the mobile paragraph block. * Update code to work with the lastest master changes * Correctly check if minHeight is undefined when setting the style of mobile paragraph block. * Blocks: Extract phrasing content to its own file to allow reuse with React Native * Remove method `setForceUpdate` that is not used. Also remove the conversion of value to boolean in if. JS does it itself. * Remove `aria-label` that is not used in RichText mobile * Convert private instance variable `lastContentSizeHeight`, to local method variable. * Use built-in `forceUpdate` method call, instead of using a private boolean variable used to skip the rendering. * Add comment for P replacement for BR
- Loading branch information
1 parent
0a4b2a5
commit 1c966a9
Showing
17 changed files
with
495 additions
and
271 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,243 @@ | ||
/** | ||
* External dependencies | ||
*/ | ||
import classnames from 'classnames'; | ||
|
||
/** | ||
* WordPress dependencies | ||
*/ | ||
import { __ } from '@wordpress/i18n'; | ||
import { | ||
Component, | ||
Fragment, | ||
} from '@wordpress/element'; | ||
import { | ||
PanelBody, | ||
ToggleControl, | ||
withFallbackStyles, | ||
} from '@wordpress/components'; | ||
import { | ||
withColors, | ||
AlignmentToolbar, | ||
BlockControls, | ||
ContrastChecker, | ||
FontSizePicker, | ||
InspectorControls, | ||
PanelColorSettings, | ||
RichText, | ||
withFontSizes, | ||
} from '@wordpress/editor'; | ||
import { createBlock } from '@wordpress/blocks'; | ||
import { compose } from '@wordpress/compose'; | ||
|
||
/** | ||
* Internal dependencies | ||
*/ | ||
import './style.scss'; | ||
|
||
const { getComputedStyle } = window; | ||
|
||
const name = 'core/paragraph'; | ||
|
||
const applyFallbackStyles = withFallbackStyles( ( node, ownProps ) => { | ||
const { textColor, backgroundColor, fontSize, customFontSize } = ownProps.attributes; | ||
const editableNode = node.querySelector( '[contenteditable="true"]' ); | ||
//verify if editableNode is available, before using getComputedStyle. | ||
const computedStyles = editableNode ? getComputedStyle( editableNode ) : null; | ||
return { | ||
fallbackBackgroundColor: backgroundColor || ! computedStyles ? undefined : computedStyles.backgroundColor, | ||
fallbackTextColor: textColor || ! computedStyles ? undefined : computedStyles.color, | ||
fallbackFontSize: fontSize || customFontSize || ! computedStyles ? undefined : parseInt( computedStyles.fontSize ) || undefined, | ||
}; | ||
} ); | ||
|
||
class ParagraphBlock extends Component { | ||
constructor() { | ||
super( ...arguments ); | ||
|
||
this.onReplace = this.onReplace.bind( this ); | ||
this.toggleDropCap = this.toggleDropCap.bind( this ); | ||
this.splitBlock = this.splitBlock.bind( this ); | ||
} | ||
|
||
onReplace( blocks ) { | ||
const { attributes, onReplace } = this.props; | ||
onReplace( blocks.map( ( block, index ) => ( | ||
index === 0 && block.name === name ? | ||
{ ...block, | ||
attributes: { | ||
...attributes, | ||
...block.attributes, | ||
}, | ||
} : | ||
block | ||
) ) ); | ||
} | ||
|
||
toggleDropCap() { | ||
const { attributes, setAttributes } = this.props; | ||
setAttributes( { dropCap: ! attributes.dropCap } ); | ||
} | ||
|
||
getDropCapHelp( checked ) { | ||
return checked ? __( 'Showing large initial letter.' ) : __( 'Toggle to show a large initial letter.' ); | ||
} | ||
|
||
/** | ||
* Split handler for RichText value, namely when content is pasted or the | ||
* user presses the Enter key. | ||
* | ||
* @param {?Array} before Optional before value, to be used as content | ||
* in place of what exists currently for the | ||
* block. If undefined, the block is deleted. | ||
* @param {?Array} after Optional after value, to be appended in a new | ||
* paragraph block to the set of blocks passed | ||
* as spread. | ||
* @param {...WPBlock} blocks Optional blocks inserted between the before | ||
* and after value blocks. | ||
*/ | ||
splitBlock( before, after, ...blocks ) { | ||
const { | ||
attributes, | ||
insertBlocksAfter, | ||
setAttributes, | ||
onReplace, | ||
} = this.props; | ||
|
||
if ( after ) { | ||
// Append "After" content as a new paragraph block to the end of | ||
// any other blocks being inserted after the current paragraph. | ||
blocks.push( createBlock( name, { content: after } ) ); | ||
} | ||
|
||
if ( blocks.length && insertBlocksAfter ) { | ||
insertBlocksAfter( blocks ); | ||
} | ||
|
||
const { content } = attributes; | ||
if ( ! before ) { | ||
// If before content is omitted, treat as intent to delete block. | ||
onReplace( [] ); | ||
} else if ( content !== before ) { | ||
// Only update content if it has in-fact changed. In case that user | ||
// has created a new paragraph at end of an existing one, the value | ||
// of before will be strictly equal to the current content. | ||
setAttributes( { content: before } ); | ||
} | ||
} | ||
|
||
render() { | ||
const { | ||
attributes, | ||
setAttributes, | ||
mergeBlocks, | ||
onReplace, | ||
className, | ||
backgroundColor, | ||
textColor, | ||
setBackgroundColor, | ||
setTextColor, | ||
fallbackBackgroundColor, | ||
fallbackTextColor, | ||
fallbackFontSize, | ||
fontSize, | ||
setFontSize, | ||
} = this.props; | ||
|
||
const { | ||
align, | ||
content, | ||
dropCap, | ||
placeholder, | ||
} = attributes; | ||
|
||
return ( | ||
<Fragment> | ||
<BlockControls> | ||
<AlignmentToolbar | ||
value={ align } | ||
onChange={ ( nextAlign ) => { | ||
setAttributes( { align: nextAlign } ); | ||
} } | ||
/> | ||
</BlockControls> | ||
<InspectorControls> | ||
<PanelBody title={ __( 'Text Settings' ) } className="blocks-font-size"> | ||
<FontSizePicker | ||
fallbackFontSize={ fallbackFontSize } | ||
value={ fontSize.size } | ||
onChange={ setFontSize } | ||
/> | ||
<ToggleControl | ||
label={ __( 'Drop Cap' ) } | ||
checked={ !! dropCap } | ||
onChange={ this.toggleDropCap } | ||
help={ this.getDropCapHelp } | ||
/> | ||
</PanelBody> | ||
<PanelColorSettings | ||
title={ __( 'Color Settings' ) } | ||
initialOpen={ false } | ||
colorSettings={ [ | ||
{ | ||
value: backgroundColor.value, | ||
onChange: setBackgroundColor, | ||
label: __( 'Background Color' ), | ||
}, | ||
{ | ||
value: textColor.value, | ||
onChange: setTextColor, | ||
label: __( 'Text Color' ), | ||
}, | ||
] } | ||
> | ||
<ContrastChecker | ||
{ ...{ | ||
textColor: textColor.value, | ||
backgroundColor: backgroundColor.value, | ||
fallbackTextColor, | ||
fallbackBackgroundColor, | ||
} } | ||
fontSize={ fontSize.size } | ||
/> | ||
</PanelColorSettings> | ||
</InspectorControls> | ||
<RichText | ||
tagName="p" | ||
className={ classnames( 'wp-block-paragraph', className, { | ||
'has-background': backgroundColor.value, | ||
'has-drop-cap': dropCap, | ||
[ backgroundColor.class ]: backgroundColor.class, | ||
[ textColor.class ]: textColor.class, | ||
[ fontSize.class ]: fontSize.class, | ||
} ) } | ||
style={ { | ||
backgroundColor: backgroundColor.value, | ||
color: textColor.value, | ||
fontSize: fontSize.size ? fontSize.size + 'px' : undefined, | ||
textAlign: align, | ||
} } | ||
value={ content } | ||
onChange={ ( nextContent ) => { | ||
setAttributes( { | ||
content: nextContent, | ||
} ); | ||
} } | ||
onSplit={ this.splitBlock } | ||
onMerge={ mergeBlocks } | ||
onReplace={ this.onReplace } | ||
onRemove={ () => onReplace( [] ) } | ||
placeholder={ placeholder || __( 'Add text or type / to add content' ) } | ||
/> | ||
</Fragment> | ||
); | ||
} | ||
} | ||
|
||
const ParagraphEdit = compose( [ | ||
withColors( 'backgroundColor', { textColor: 'color' } ), | ||
withFontSizes( 'fontSize' ), | ||
applyFallbackStyles, | ||
] )( ParagraphBlock ); | ||
|
||
export default ParagraphEdit; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
/** | ||
* External dependencies | ||
*/ | ||
import { View } from 'react-native'; | ||
|
||
/** | ||
* WordPress dependencies | ||
*/ | ||
import { __ } from '@wordpress/i18n'; | ||
import { Component } from '@wordpress/element'; | ||
import { parse } from '@wordpress/blocks'; | ||
import { RichText } from '@wordpress/editor'; | ||
|
||
const minHeight = 50; | ||
|
||
class ParagraphEdit extends Component { | ||
render() { | ||
const { | ||
attributes, | ||
setAttributes, | ||
style, | ||
} = this.props; | ||
|
||
const { | ||
placeholder, | ||
} = attributes; | ||
|
||
return ( | ||
<View> | ||
<RichText | ||
content={ { contentTree: attributes.content, eventCount: attributes.eventCount } } | ||
style={ { | ||
...style, | ||
minHeight: Math.max( minHeight, typeof attributes.aztecHeight === 'undefined' ? 0 : attributes.aztecHeight ), | ||
} } | ||
onChange={ ( event ) => { | ||
// Create a React Tree from the new HTML | ||
const newParaBlock = parse( '<!-- wp:paragraph --><p>' + event.content + '</p><!-- /wp:paragraph -->' )[ 0 ]; | ||
setAttributes( { | ||
...this.props.attributes, | ||
content: newParaBlock.attributes.content, | ||
eventCount: event.eventCount, | ||
} ); | ||
} | ||
} | ||
onContentSizeChange={ ( event ) => { | ||
setAttributes( { | ||
...this.props.attributes, | ||
aztecHeight: event.aztecHeight, | ||
} ); | ||
} | ||
} | ||
placeholder={ placeholder || __( 'Add text or type / to add content' ) } | ||
/> | ||
</View> | ||
); | ||
} | ||
} | ||
|
||
export default ParagraphEdit; |
Oops, something went wrong.