diff --git a/packages/block-editor/src/components/rich-text/index.native.js b/packages/block-editor/src/components/rich-text/index.native.js index fe04011866fd8d..e1e12cde222ace 100644 --- a/packages/block-editor/src/components/rich-text/index.native.js +++ b/packages/block-editor/src/components/rich-text/index.native.js @@ -113,6 +113,7 @@ function RichTextWrapper( disableSuggestions, disableAutocorrection, containerWidth, + onEnter: onCustomEnter, ...props }, forwardedRef @@ -344,6 +345,10 @@ function RichTextWrapper( } } + if ( onCustomEnter ) { + onCustomEnter(); + } + if ( multiline ) { if ( shiftKey ) { if ( ! disableLineBreaks ) { diff --git a/packages/block-library/src/list-item/edit.native.js b/packages/block-library/src/list-item/edit.native.js index 5326cbd79b0e47..dcd20f11c9d5e8 100644 --- a/packages/block-library/src/list-item/edit.native.js +++ b/packages/block-library/src/list-item/edit.native.js @@ -16,12 +16,12 @@ import { import { __ } from '@wordpress/i18n'; import { usePreferredColorSchemeStyle } from '@wordpress/compose'; import { useSelect } from '@wordpress/data'; -import { useState, useCallback } from '@wordpress/element'; +import { useState, useCallback, useRef } from '@wordpress/element'; /** * Internal dependencies */ -import { useSplit, useMerge } from './hooks'; +import { useSplit, useMerge, useEnter } from './hooks'; import { convertToListItems } from './utils'; import { IndentUI } from './edit.js'; import styles from './style.scss'; @@ -116,8 +116,26 @@ export default function ListItemEdit( { } ), }; + const preventDefault = useRef( false ); + const { onEnter } = useEnter( { content, clientId }, preventDefault ); const onSplit = useSplit( clientId ); const onMerge = useMerge( clientId ); + const onSplitList = useCallback( + ( value ) => { + if ( ! preventDefault.current ) { + return onSplit( value ); + } + }, + [ clientId, onSplit ] + ); + const onReplaceList = useCallback( + ( blocks, ...args ) => { + if ( ! preventDefault.current ) { + onReplace( convertToListItems( blocks ), ...args ); + } + }, + [ clientId, onReplace, convertToListItems ] + ); const onLayout = useCallback( ( { nativeEvent } ) => { setContentWidth( ( prevState ) => { const { width } = nativeEvent.layout; @@ -158,11 +176,10 @@ export default function ListItemEdit( { placeholderTextColor={ defaultPlaceholderTextColorWithOpacity } - onSplit={ onSplit } + onSplit={ onSplitList } onMerge={ onMerge } - onReplace={ ( blocks, ...args ) => { - onReplace( convertToListItems( blocks ), ...args ); - } } + onReplace={ onReplaceList } + onEnter={ onEnter } style={ styleWithPlaceholderOpacity } deleteEnter={ true } containerWidth={ contentWidth } diff --git a/packages/block-library/src/list-item/hooks/use-enter.native.js b/packages/block-library/src/list-item/hooks/use-enter.native.js new file mode 100644 index 00000000000000..d3be5f1ea0e1bb --- /dev/null +++ b/packages/block-library/src/list-item/hooks/use-enter.native.js @@ -0,0 +1,77 @@ +/** + * WordPress dependencies + */ +import { + createBlock, + getDefaultBlockName, + cloneBlock, +} from '@wordpress/blocks'; +import { useRef } from '@wordpress/element'; +import { useSelect, useDispatch } from '@wordpress/data'; +import { store as blockEditorStore } from '@wordpress/block-editor'; + +/** + * Internal dependencies + */ +import useOutdentListItem from './use-outdent-list-item'; + +export default function useEnter( props, preventDefault ) { + const { replaceBlocks, selectionChange } = useDispatch( blockEditorStore ); + const { getBlock, getBlockRootClientId, getBlockIndex } = + useSelect( blockEditorStore ); + const propsRef = useRef( props ); + propsRef.current = props; + const [ canOutdent, outdentListItem ] = useOutdentListItem( + propsRef.current.clientId + ); + + return { + onEnter() { + const { content, clientId } = propsRef.current; + if ( content.length ) { + return; + } + preventDefault.current = true; + if ( canOutdent ) { + outdentListItem(); + return; + } + // Here we are in top level list so we need to split. + const topParentListBlock = getBlock( + getBlockRootClientId( clientId ) + ); + const blockIndex = getBlockIndex( clientId ); + const head = cloneBlock( { + ...topParentListBlock, + innerBlocks: topParentListBlock.innerBlocks.slice( + 0, + blockIndex + ), + } ); + const middle = createBlock( getDefaultBlockName() ); + // Last list item might contain a `list` block innerBlock + // In that case append remaining innerBlocks blocks. + const after = [ + ...( topParentListBlock.innerBlocks[ blockIndex ] + .innerBlocks[ 0 ]?.innerBlocks || [] ), + ...topParentListBlock.innerBlocks.slice( blockIndex + 1 ), + ]; + const tail = after.length + ? [ + cloneBlock( { + ...topParentListBlock, + innerBlocks: after, + } ), + ] + : []; + replaceBlocks( + topParentListBlock.clientId, + [ head, middle, ...tail ], + 1 + ); + // We manually change the selection here because we are replacing + // a different block than the selected one. + selectionChange( middle.clientId ); + }, + }; +} diff --git a/packages/react-native-aztec/package.json b/packages/react-native-aztec/package.json index 4534cb47204b2a..7ed083784390fd 100644 --- a/packages/react-native-aztec/package.json +++ b/packages/react-native-aztec/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/react-native-aztec", - "version": "1.82.0", + "version": "1.82.1", "description": "Aztec view for react-native.", "private": true, "author": "The WordPress Contributors", diff --git a/packages/react-native-bridge/package.json b/packages/react-native-bridge/package.json index 99e3a19111a2b2..f9a4fab7459198 100644 --- a/packages/react-native-bridge/package.json +++ b/packages/react-native-bridge/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/react-native-bridge", - "version": "1.82.0", + "version": "1.82.1", "description": "Native bridge library used to integrate the block editor into a native App.", "private": true, "author": "The WordPress Contributors", diff --git a/packages/react-native-editor/CHANGELOG.md b/packages/react-native-editor/CHANGELOG.md index 79fca8226e8edd..72409d9ac9e0fd 100644 --- a/packages/react-native-editor/CHANGELOG.md +++ b/packages/react-native-editor/CHANGELOG.md @@ -11,6 +11,9 @@ For each user feature we should also add a importance categorization label to i ## Unreleased +## 1.82.1 +- [**] List block v2: Fix issues splitting or merging paragraphs into the block [#43949] + ## 1.82.0 - [*] [iOS] Explicitly set tint color for action sheets to always be blue [#43759] diff --git a/packages/react-native-editor/ios/Podfile.lock b/packages/react-native-editor/ios/Podfile.lock index f93385757e38a7..555e7b6dcb7ba6 100644 --- a/packages/react-native-editor/ios/Podfile.lock +++ b/packages/react-native-editor/ios/Podfile.lock @@ -13,7 +13,7 @@ PODS: - ReactCommon/turbomodule/core (= 0.66.2) - fmt (6.2.1) - glog (0.3.5) - - Gutenberg (1.82.0): + - Gutenberg (1.82.1): - React-Core (= 0.66.2) - React-CoreModules (= 0.66.2) - React-RCTImage (= 0.66.2) @@ -350,7 +350,7 @@ PODS: - React-Core - RNSVG (9.13.6): - React-Core - - RNTAztecView (1.82.0): + - RNTAztecView (1.82.1): - React-Core - WordPress-Aztec-iOS (~> 1.19.8) - SDWebImage (5.11.1): @@ -528,7 +528,7 @@ SPEC CHECKSUMS: FBReactNativeSpec: 18438b1c04ce502ed681cd19db3f4508964c082a fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9 glog: 5337263514dd6f09803962437687240c5dc39aa4 - Gutenberg: ecbe9a4c5cb35fcabf1f7b524f56e4242fb9ee9f + Gutenberg: 4c406229dfc941c04dc1923ef661bc42cdf48c42 libwebp: 98a37e597e40bfdb4c911fc98f2c53d0b12d05fc RCT-Folly: a21c126816d8025b547704b777a2ba552f3d9fa9 RCTRequired: 5e9e85f48da8dd447f5834ce14c6799ea8c7f41a @@ -569,7 +569,7 @@ SPEC CHECKSUMS: RNReanimated: b413cc7aa3e2a740d9804cda3a9396a68f9eea7f RNScreens: 953633729a42e23ad0c93574d676b361e3335e8b RNSVG: 36a7359c428dcb7c6bce1cc546fbfebe069809b0 - RNTAztecView: d147b75ad3ec3fd43bce60c7c4d96e93b7294090 + RNTAztecView: 8cb0bd37845a25eab416611e92d5adaf5a4931ac SDWebImage: a7f831e1a65eb5e285e3fb046a23fcfbf08e696d SDWebImageWebPCoder: 908b83b6adda48effe7667cd2b7f78c897e5111d WordPress-Aztec-iOS: 7d11d598f14c82c727c08b56bd35fbeb7dafb504 diff --git a/packages/react-native-editor/package.json b/packages/react-native-editor/package.json index 0077f7d21b54cc..670704848ea5ac 100644 --- a/packages/react-native-editor/package.json +++ b/packages/react-native-editor/package.json @@ -1,6 +1,6 @@ { "name": "@wordpress/react-native-editor", - "version": "1.82.0", + "version": "1.82.1", "description": "Mobile WordPress gutenberg editor.", "author": "The WordPress Contributors", "license": "GPL-2.0-or-later",