From 8ba701ea077fc528aedd9a365b91b7259516b2df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ella=20van=C2=A0Durpe?= Date: Wed, 13 Jul 2022 18:41:34 +0200 Subject: [PATCH 1/5] Add setting to display rich text toolbar inline --- .../src/components/observe-typing/index.js | 71 ++++++++++++++----- .../rich-text/format-toolbar-container.js | 20 +++++- .../src/components/rich-text/index.js | 1 + .../src/components/preferences-modal/index.js | 7 ++ packages/edit-post/src/editor.js | 3 + .../provider/use-block-editor-settings.js | 1 + 6 files changed, 81 insertions(+), 22 deletions(-) diff --git a/packages/block-editor/src/components/observe-typing/index.js b/packages/block-editor/src/components/observe-typing/index.js index c2d86f9934717..1bcf3fdfab16c 100644 --- a/packages/block-editor/src/components/observe-typing/index.js +++ b/packages/block-editor/src/components/observe-typing/index.js @@ -53,10 +53,13 @@ function isKeyDownEligibleForStartTyping( event ) { * element. */ export function useMouseMoveTypingReset() { - const isTyping = useSelect( - ( select ) => select( blockEditorStore ).isTyping(), - [] - ); + const { isTyping, hasInlineToolbar } = useSelect( ( select ) => { + const { isTyping: _isTyping, getSettings } = select( blockEditorStore ); + return { + isTyping: _isTyping(), + hasInlineToolbar: getSettings().hasInlineToolbar, + }; + }, [] ); const { stopTyping } = useDispatch( blockEditorStore ); return useRefEffect( @@ -66,6 +69,8 @@ export function useMouseMoveTypingReset() { } const { ownerDocument } = node; + const { defaultView } = ownerDocument; + const selection = defaultView.getSelection(); let lastClientX; let lastClientY; @@ -77,6 +82,10 @@ export function useMouseMoveTypingReset() { function stopTypingOnMouseMove( event ) { const { clientX, clientY } = event; + if ( hasInlineToolbar && ! selection.isCollapsed ) { + return; + } + // We need to check that the mouse really moved because Safari // triggers mousemove events when shift or ctrl are pressed. if ( @@ -115,16 +124,25 @@ export function useMouseMoveTypingReset() { * field, presses ESC or TAB, or moves the mouse in the document. */ export function useTypingObserver() { - const isTyping = useSelect( ( select ) => - select( blockEditorStore ).isTyping() - ); + const { isTyping, hasInlineToolbar } = useSelect( ( select ) => { + const { isTyping: _isTyping, getSettings } = select( blockEditorStore ); + return { + isTyping: _isTyping(), + hasInlineToolbar: getSettings().hasInlineToolbar, + }; + }, [] ); const { startTyping, stopTyping } = useDispatch( blockEditorStore ); - const ref1 = useMouseMoveTypingReset(); + const ref1 = useMouseMoveTypingReset( { + isTyping, + hasInlineToolbar, + stopTyping, + } ); const ref2 = useRefEffect( ( node ) => { const { ownerDocument } = node; const { defaultView } = ownerDocument; + const selection = defaultView.getSelection(); // Listeners to stop typing should only be added when typing. // Listeners to start typing should only be added when not typing. @@ -170,22 +188,20 @@ export function useTypingObserver() { * uncollapsed (shift) selection. */ function stopTypingOnSelectionUncollapse() { - const selection = defaultView.getSelection(); - const isCollapsed = - selection.rangeCount > 0 && - selection.getRangeAt( 0 ).collapsed; - - if ( ! isCollapsed ) { + if ( ! selection.isCollapsed ) { stopTyping(); } } node.addEventListener( 'focus', stopTypingOnNonTextField ); node.addEventListener( 'keydown', stopTypingOnEscapeKey ); - ownerDocument.addEventListener( - 'selectionchange', - stopTypingOnSelectionUncollapse - ); + + if ( ! hasInlineToolbar ) { + ownerDocument.addEventListener( + 'selectionchange', + stopTypingOnSelectionUncollapse + ); + } return () => { defaultView.clearTimeout( timerId ); @@ -234,15 +250,32 @@ export function useTypingObserver() { startTyping(); } + function startTypingOnSelection() { + if ( ! selection.isCollapsed ) { + startTyping(); + } + } + node.addEventListener( 'keypress', startTypingInTextField ); node.addEventListener( 'keydown', startTypingInTextField ); + if ( hasInlineToolbar ) { + ownerDocument.addEventListener( + 'selectionchange', + startTypingOnSelection + ); + } + return () => { node.removeEventListener( 'keypress', startTypingInTextField ); node.removeEventListener( 'keydown', startTypingInTextField ); + ownerDocument.removeEventListener( + 'selectionchange', + startTypingOnSelection + ); }; }, - [ isTyping, startTyping, stopTyping ] + [ isTyping, hasInlineToolbar, startTyping, stopTyping ] ); return useMergeRefs( [ ref1, ref2 ] ); diff --git a/packages/block-editor/src/components/rich-text/format-toolbar-container.js b/packages/block-editor/src/components/rich-text/format-toolbar-container.js index 08ea1e7e66fdf..73ce2f643fed9 100644 --- a/packages/block-editor/src/components/rich-text/format-toolbar-container.js +++ b/packages/block-editor/src/components/rich-text/format-toolbar-container.js @@ -2,21 +2,34 @@ * WordPress dependencies */ import { Popover, ToolbarGroup } from '@wordpress/components'; +import { useSelect } from '@wordpress/data'; +import { isCollapsed, useAnchorRef } from '@wordpress/rich-text'; /** * Internal dependencies */ import BlockControls from '../block-controls'; import FormatToolbar from './format-toolbar'; +import { store as blockEditorStore } from '../../store'; + +const FormatToolbarContainer = ( { inline, anchorRef, value } ) => { + const hasInlineToolbar = useSelect( + ( select ) => select( blockEditorStore ).getSettings().hasInlineToolbar, + [] + ); + const selectionRef = useAnchorRef( { ref: anchorRef, value } ); + + if ( hasInlineToolbar || inline ) { + if ( hasInlineToolbar && isCollapsed( value ) ) { + return null; + } -const FormatToolbarContainer = ( { inline, anchorRef } ) => { - if ( inline ) { // Render in popover. return ( @@ -28,6 +41,7 @@ const FormatToolbarContainer = ( { inline, anchorRef } ) => { ); } + // Render regular toolbar. return ( diff --git a/packages/block-editor/src/components/rich-text/index.js b/packages/block-editor/src/components/rich-text/index.js index ef3e4d2d3a318..abf9068a356a7 100644 --- a/packages/block-editor/src/components/rich-text/index.js +++ b/packages/block-editor/src/components/rich-text/index.js @@ -344,6 +344,7 @@ function RichTextWrapper( ) } + Date: Wed, 13 Jul 2022 19:19:20 +0200 Subject: [PATCH 2/5] Show toolbar for active formats --- .../src/components/observe-typing/index.js | 34 +++---------------- .../rich-text/format-toolbar-container.js | 29 +++++++++++++--- packages/rich-text/README.md | 13 +++++++ packages/rich-text/src/index.js | 1 + 4 files changed, 43 insertions(+), 34 deletions(-) diff --git a/packages/block-editor/src/components/observe-typing/index.js b/packages/block-editor/src/components/observe-typing/index.js index 1bcf3fdfab16c..9814437a1273f 100644 --- a/packages/block-editor/src/components/observe-typing/index.js +++ b/packages/block-editor/src/components/observe-typing/index.js @@ -53,13 +53,10 @@ function isKeyDownEligibleForStartTyping( event ) { * element. */ export function useMouseMoveTypingReset() { - const { isTyping, hasInlineToolbar } = useSelect( ( select ) => { - const { isTyping: _isTyping, getSettings } = select( blockEditorStore ); - return { - isTyping: _isTyping(), - hasInlineToolbar: getSettings().hasInlineToolbar, - }; - }, [] ); + const isTyping = useSelect( + ( select ) => select( blockEditorStore ).isTyping(), + [] + ); const { stopTyping } = useDispatch( blockEditorStore ); return useRefEffect( @@ -69,8 +66,6 @@ export function useMouseMoveTypingReset() { } const { ownerDocument } = node; - const { defaultView } = ownerDocument; - const selection = defaultView.getSelection(); let lastClientX; let lastClientY; @@ -82,10 +77,6 @@ export function useMouseMoveTypingReset() { function stopTypingOnMouseMove( event ) { const { clientX, clientY } = event; - if ( hasInlineToolbar && ! selection.isCollapsed ) { - return; - } - // We need to check that the mouse really moved because Safari // triggers mousemove events when shift or ctrl are pressed. if ( @@ -250,29 +241,12 @@ export function useTypingObserver() { startTyping(); } - function startTypingOnSelection() { - if ( ! selection.isCollapsed ) { - startTyping(); - } - } - node.addEventListener( 'keypress', startTypingInTextField ); node.addEventListener( 'keydown', startTypingInTextField ); - if ( hasInlineToolbar ) { - ownerDocument.addEventListener( - 'selectionchange', - startTypingOnSelection - ); - } - return () => { node.removeEventListener( 'keypress', startTypingInTextField ); node.removeEventListener( 'keydown', startTypingInTextField ); - ownerDocument.removeEventListener( - 'selectionchange', - startTypingOnSelection - ); }; }, [ isTyping, hasInlineToolbar, startTyping, stopTyping ] diff --git a/packages/block-editor/src/components/rich-text/format-toolbar-container.js b/packages/block-editor/src/components/rich-text/format-toolbar-container.js index 73ce2f643fed9..5579d970345c7 100644 --- a/packages/block-editor/src/components/rich-text/format-toolbar-container.js +++ b/packages/block-editor/src/components/rich-text/format-toolbar-container.js @@ -3,7 +3,12 @@ */ import { Popover, ToolbarGroup } from '@wordpress/components'; import { useSelect } from '@wordpress/data'; -import { isCollapsed, useAnchorRef } from '@wordpress/rich-text'; +import { + isCollapsed, + getActiveFormats, + useAnchorRef, + store as richTextStore, +} from '@wordpress/rich-text'; /** * Internal dependencies @@ -17,17 +22,33 @@ const FormatToolbarContainer = ( { inline, anchorRef, value } ) => { ( select ) => select( blockEditorStore ).getSettings().hasInlineToolbar, [] ); - const selectionRef = useAnchorRef( { ref: anchorRef, value } ); + const activeFormats = getActiveFormats( value ); + const lastFormat = activeFormats[ activeFormats.length - 1 ]; + const lastFormatType = lastFormat?.type; + const settings = useSelect( + ( select ) => + select( richTextStore ).getFormatType( lastFormatType ) || {}, + [ lastFormatType ] + ); + const selectionRef = useAnchorRef( { + ref: anchorRef, + value, + settings, + } ); if ( hasInlineToolbar || inline ) { - if ( hasInlineToolbar && isCollapsed( value ) ) { + if ( + hasInlineToolbar && + isCollapsed( value ) && + ! activeFormats.length + ) { return null; } // Render in popover. return ( Date: Wed, 13 Jul 2022 19:39:36 +0200 Subject: [PATCH 3/5] polish --- .../src/components/observe-typing/index.js | 6 +- .../rich-text/format-toolbar-container.js | 70 +++++++++++-------- 2 files changed, 43 insertions(+), 33 deletions(-) diff --git a/packages/block-editor/src/components/observe-typing/index.js b/packages/block-editor/src/components/observe-typing/index.js index 9814437a1273f..08764f5939a13 100644 --- a/packages/block-editor/src/components/observe-typing/index.js +++ b/packages/block-editor/src/components/observe-typing/index.js @@ -124,11 +124,7 @@ export function useTypingObserver() { }, [] ); const { startTyping, stopTyping } = useDispatch( blockEditorStore ); - const ref1 = useMouseMoveTypingReset( { - isTyping, - hasInlineToolbar, - stopTyping, - } ); + const ref1 = useMouseMoveTypingReset(); const ref2 = useRefEffect( ( node ) => { const { ownerDocument } = node; diff --git a/packages/block-editor/src/components/rich-text/format-toolbar-container.js b/packages/block-editor/src/components/rich-text/format-toolbar-container.js index 5579d970345c7..e3a953be56d27 100644 --- a/packages/block-editor/src/components/rich-text/format-toolbar-container.js +++ b/packages/block-editor/src/components/rich-text/format-toolbar-container.js @@ -17,17 +17,11 @@ import BlockControls from '../block-controls'; import FormatToolbar from './format-toolbar'; import { store as blockEditorStore } from '../../store'; -const FormatToolbarContainer = ( { inline, anchorRef, value } ) => { - const hasInlineToolbar = useSelect( - ( select ) => select( blockEditorStore ).getSettings().hasInlineToolbar, - [] - ); - const activeFormats = getActiveFormats( value ); +function InlineSelectionToolbar( { value, anchorRef, activeFormats } ) { const lastFormat = activeFormats[ activeFormats.length - 1 ]; const lastFormatType = lastFormat?.type; const settings = useSelect( - ( select ) => - select( richTextStore ).getFormatType( lastFormatType ) || {}, + ( select ) => select( richTextStore ).getFormatType( lastFormatType ), [ lastFormatType ] ); const selectionRef = useAnchorRef( { @@ -36,30 +30,50 @@ const FormatToolbarContainer = ( { inline, anchorRef, value } ) => { settings, } ); - if ( hasInlineToolbar || inline ) { - if ( - hasInlineToolbar && - isCollapsed( value ) && - ! activeFormats.length - ) { + return ; +} + +function InlineToolbar( { anchorRef } ) { + return ( + +
+ + + +
+
+ ); +} + +const FormatToolbarContainer = ( { inline, anchorRef, value } ) => { + const hasInlineToolbar = useSelect( + ( select ) => select( blockEditorStore ).getSettings().hasInlineToolbar, + [] + ); + + if ( inline ) { + return ; + } + + if ( hasInlineToolbar ) { + const activeFormats = getActiveFormats( value ); + + if ( isCollapsed( value ) && ! activeFormats.length ) { return null; } - // Render in popover. return ( - -
- - - -
-
+ ); } From 7df9544c49878b02aa28e9c9d22ba90ae268bd41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ella=20van=C2=A0Durpe?= Date: Thu, 14 Jul 2022 13:02:29 +0200 Subject: [PATCH 4/5] Remove option from UI --- .../edit-post/src/components/preferences-modal/index.js | 7 ------- 1 file changed, 7 deletions(-) diff --git a/packages/edit-post/src/components/preferences-modal/index.js b/packages/edit-post/src/components/preferences-modal/index.js index c62ef1dc57fd9..9e3e1a53f4a87 100644 --- a/packages/edit-post/src/components/preferences-modal/index.js +++ b/packages/edit-post/src/components/preferences-modal/index.js @@ -123,13 +123,6 @@ export default function EditPostPreferencesModal() { ) } label={ __( 'Reduce the interface' ) } /> - Date: Thu, 14 Jul 2022 13:05:13 +0200 Subject: [PATCH 5/5] Show on top --- .../src/components/rich-text/format-toolbar-container.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/block-editor/src/components/rich-text/format-toolbar-container.js b/packages/block-editor/src/components/rich-text/format-toolbar-container.js index e3a953be56d27..24a931dc79175 100644 --- a/packages/block-editor/src/components/rich-text/format-toolbar-container.js +++ b/packages/block-editor/src/components/rich-text/format-toolbar-container.js @@ -36,7 +36,7 @@ function InlineSelectionToolbar( { value, anchorRef, activeFormats } ) { function InlineToolbar( { anchorRef } ) { return (