Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement list block in React Native #14636

Merged
merged 31 commits into from
Apr 5, 2019
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
bd83d8f
Make sure multiline property is filtered out of props on save.
SergioEstevao Mar 5, 2019
8ed9cc0
Send block edit parameters using the context.
SergioEstevao Mar 5, 2019
e0d7cf6
Add multiline variables to allow proper parsing and saving of propert…
SergioEstevao Mar 5, 2019
eb33f84
Add list edit toolbar options
SergioEstevao Mar 5, 2019
c64dd5a
Add multiline property.
SergioEstevao Mar 25, 2019
f0a1e21
Add list block to mobile gb.
SergioEstevao Mar 4, 2019
73aaa4f
Move list-edit.native.js to new location.
SergioEstevao Mar 20, 2019
b6938aa
Make block edit send down the onFocus property.
SergioEstevao Mar 26, 2019
74f77cf
Handle case where unstableSplit is passed has prop.
SergioEstevao Mar 26, 2019
79f408c
Pass multiline tags to serialiser.
SergioEstevao Mar 27, 2019
1f12a9f
Use the format-lib for handling "Enter" in lists
hypest Mar 28, 2019
cc8a4e8
Merge branch 'master' into rnmobile/lists2
SergioEstevao Mar 29, 2019
ca338c2
Force selection reset on split
hypest Mar 29, 2019
076936f
Add multiline wrapper tags to formatToValue.
SergioEstevao Mar 29, 2019
6ff97b8
Merge branch 'rnmobile/lists2' of https://github.com/WordPress/gutenb…
SergioEstevao Mar 29, 2019
73fbd38
Remove unnecessary code.
SergioEstevao Mar 29, 2019
e07498e
Force rich-text text update on list type change
hypest Mar 29, 2019
f40852c
Merge branch 'master' into rnmobile/lists2
SergioEstevao Apr 2, 2019
7fb36f6
Merge branch 'master' into rnmobile/lists2
SergioEstevao Apr 3, 2019
9145a6d
Merge branch 'master' into rnmobile/lists2
SergioEstevao Apr 4, 2019
58eae26
Disable indent and outdent.
SergioEstevao Apr 4, 2019
08318ca
Enable toggling list type of nested lists
hypest Apr 4, 2019
9dcd23b
Update list type toolbar button on native mobile
hypest Apr 4, 2019
fd62f01
Include diff missed by previous commit
hypest Apr 4, 2019
66e971d
Rename to denote that it's about lines
hypest Apr 5, 2019
da0e1a7
Split into separate functions and mark unstable
hypest Apr 5, 2019
eb009e8
Add missing JSDoc param
Tug Apr 5, 2019
cc5666e
Update snapshot for BlockControls
Tug Apr 5, 2019
91f790c
Merge branch 'master' into rnmobile/lists2
SergioEstevao Apr 5, 2019
4451cb3
Move isActiveListType, isListRootSelected to rich-text package
hypest Apr 5, 2019
97ac0fb
Remove excess empty line
hypest Apr 5, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion packages/block-editor/src/components/block-edit/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,13 @@ class BlockEdit extends Component {
}

static getDerivedStateFromProps( props ) {
const { clientId, name, isSelected } = props;
const { clientId, name, isSelected, onFocus } = props;

return {
name,
isSelected,
clientId,
onFocus,
};
}

Expand Down
62 changes: 59 additions & 3 deletions packages/block-editor/src/components/rich-text/index.native.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ import { isURL } from '@wordpress/url';
*/
import FormatEdit from './format-edit';
import FormatToolbar from './format-toolbar';
import { withBlockEditContext } from '../block-edit/context';
import { ListEdit } from './list-edit';

import styles from './style.scss';

Expand Down Expand Up @@ -70,8 +72,19 @@ const gutenbergFormatNamesToAztec = {
};

export class RichText extends Component {
constructor() {
constructor( { multiline } ) {
super( ...arguments );

this.isMultiline = false;
if ( multiline === true || multiline === 'p' || multiline === 'li' ) {
this.multilineTag = multiline === true ? 'p' : multiline;
this.isMultiline = true;
}

if ( this.multilineTag === 'li' ) {
this.multilineWrapperTags = [ 'ul', 'ol' ];
}

this.isIOS = Platform.OS === 'ios';
this.onChange = this.onChange.bind( this );
this.onEnter = this.onEnter.bind( this );
Expand Down Expand Up @@ -501,6 +514,7 @@ export class RichText extends Component {
style,
formattingControls,
isSelected,
onTagNameChange,
} = this.props;

const record = this.getRecord();
Expand All @@ -522,6 +536,14 @@ export class RichText extends Component {

return (
<View>
{ isSelected && this.multilineTag === 'li' && (
<ListEdit
onTagNameChange={ onTagNameChange }
tagName={ tagName }
value={ record }
onChange={ this.onFormatChange }
/>
) }
{ isSelected && (
<BlockFormatControls>
<FormatToolbar controls={ formattingControls } />
Expand Down Expand Up @@ -561,6 +583,7 @@ export class RichText extends Component {
fontWeight={ this.props.fontWeight }
fontStyle={ this.props.fontStyle }
disableEditingMenu={ this.props.disableEditingMenu }
isMultiline={ this.isMultiline }
/>
{ isSelected && <FormatEdit value={ record } onChange={ this.onFormatChange } /> }
</View>
Expand All @@ -582,13 +605,46 @@ const RichTextContainer = compose( [
formatTypes: getFormatTypes(),
};
} ),
withBlockEditContext( ( context, ownProps ) => {
// When explicitly set as not selected, do nothing.
if ( ownProps.isSelected === false ) {
return {
clientId: context.clientId,
};
}
// When explicitly set as selected, use the value stored in the context instead.
if ( ownProps.isSelected === true ) {
return {
isSelected: context.isSelected,
clientId: context.clientId,
};
}

// Ensures that only one RichText component can be focused.
return {
clientId: context.clientId,
isSelected: context.isSelected,
onFocus: context.onFocus,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I saw that but it looks we don't use the same logic on the native part on our block manager.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how is going your solution work with multiple RichText controls included in a single block?

};
} ),
] )( RichText );

RichTextContainer.Content = ( { value, format, tagName: Tag, ...props } ) => {
RichTextContainer.Content = ( { value, format, tagName: Tag, multiline, ...props } ) => {
let content;
let html = value;
let MultilineTag;

if ( multiline === true || multiline === 'p' || multiline === 'li' ) {
MultilineTag = multiline === true ? 'p' : multiline;
}

if ( ! html && MultilineTag ) {
html = `<${ MultilineTag }></${ MultilineTag }>`;
}

switch ( format ) {
case 'string':
content = <RawHTML>{ value }</RawHTML>;
content = <RawHTML>{ html }</RawHTML>;
break;
}

Expand Down
93 changes: 93 additions & 0 deletions packages/block-editor/src/components/rich-text/list-edit.native.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
/**
* WordPress dependencies
*/

import { Toolbar } from '@wordpress/components';
import { __ } from '@wordpress/i18n';
import {
indentListItems,
outdentListItems,
changeListType,
} from '@wordpress/rich-text';

/**
* Internal dependencies
*/

import BlockFormatControls from '../block-format-controls';

/**
* Whether or not the root list is selected.
*
* @return {boolean} True if the root list or nothing is selected, false if an
* inner list is selected.
*/
function isListRootSelected() {
// Consider the root list selected if nothing is selected.
return true;
}

/**
* Wether or not the selected list has the given tag name.
*
* @param {string} tagName The tag name the list should have.
* @param {string} rootTagName The current root tag name, to compare with in
* case nothing is selected.
*
* @return {boolean} [description]
*/
function isActiveListType( tagName, rootTagName ) {
return tagName === rootTagName;
}

export const ListEdit = ( {
onTagNameChange,
tagName,
value,
onChange,
} ) => (
<BlockFormatControls>
<Toolbar
controls={ [
onTagNameChange && {
icon: 'editor-ul',
title: __( 'Convert to unordered list' ),
isActive: isActiveListType( 'ul', tagName ),
onClick() {
onChange( changeListType( value, { type: 'ul' } ) );

if ( isListRootSelected() ) {
onTagNameChange( 'ul' );
}
},
},
onTagNameChange && {
icon: 'editor-ol',
title: __( 'Convert to ordered list' ),
isActive: isActiveListType( 'ol', tagName ),
onClick() {
onChange( changeListType( value, { type: 'ol' } ) );

if ( isListRootSelected() ) {
onTagNameChange( 'ol' );
}
},
},
{
icon: 'editor-outdent',
title: __( 'Outdent list item' ),
onClick: () => {
onChange( outdentListItems( value ) );
},
},
{
icon: 'editor-indent',
title: __( 'Indent list item' ),
onClick: () => {
onChange( indentListItems( value, { type: tagName } ) );
},
},
].filter( Boolean ) }
/>
</BlockFormatControls>
);
2 changes: 2 additions & 0 deletions packages/block-library/src/index.native.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import * as more from './more';
import * as paragraph from './paragraph';
import * as image from './image';
import * as nextpage from './nextpage';
import * as list from './list';

export const registerCoreBlocks = () => {
[
Expand All @@ -24,6 +25,7 @@ export const registerCoreBlocks = () => {
more,
image,
nextpage,
list,
].forEach( ( { name, settings } ) => {
registerBlockType( name, settings );
} );
Expand Down