From 92876267d35cf0035ddc0f13053281820a4978cc Mon Sep 17 00:00:00 2001 From: Ella Date: Tue, 7 May 2024 11:30:38 +0900 Subject: [PATCH 1/6] Zoom out: scroll block on insert --- .../block-list/use-block-props/index.js | 24 ++++++++++++++++++- packages/block-editor/src/store/selectors.js | 2 +- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/packages/block-editor/src/components/block-list/use-block-props/index.js b/packages/block-editor/src/components/block-list/use-block-props/index.js index 46ebe502be07e..b263c2086b12b 100644 --- a/packages/block-editor/src/components/block-list/use-block-props/index.js +++ b/packages/block-editor/src/components/block-list/use-block-props/index.js @@ -9,7 +9,7 @@ import clsx from 'clsx'; import { useContext } from '@wordpress/element'; import { __, sprintf } from '@wordpress/i18n'; import { __unstableGetBlockProps as getBlockProps } from '@wordpress/blocks'; -import { useMergeRefs, useDisabled } from '@wordpress/compose'; +import { useMergeRefs, useDisabled, useRefEffect } from '@wordpress/compose'; import warning from '@wordpress/warning'; /** @@ -122,6 +122,28 @@ export function useBlockProps( props = {}, { __unstableIsHtml } = {} ) { clientId, isEnabled: name === 'core/block' || templateLock === 'contentOnly', } ), + useRefEffect( + ( node ) => { + if ( isSelected ) { + const { defaultView } = node.ownerDocument; + const observer = new defaultView.IntersectionObserver( + ( entries ) => { + // Once observing starts, we always get an initial + // entry with the intersecting state. + if ( ! entries[ 0 ].isIntersecting ) { + node.scrollIntoView(); + observer.disconnect(); + } + } + ); + observer.observe( node ); + return () => { + observer.disconnect(); + }; + } + }, + [ isSelected ] + ), ] ); const blockEditContext = useBlockEditContext(); diff --git a/packages/block-editor/src/store/selectors.js b/packages/block-editor/src/store/selectors.js index 4ce85afb8cfd1..0d6c4e921594b 100644 --- a/packages/block-editor/src/store/selectors.js +++ b/packages/block-editor/src/store/selectors.js @@ -2751,7 +2751,7 @@ export function wasBlockJustInserted( state, clientId, source ) { * @return {boolean} True if the block is visible. */ export function isBlockVisible( state, clientId ) { - return state.blockVisibility?.[ clientId ] ?? true; + return state.blockVisibility?.[ clientId ]; } /** From 0e25145a4cf807eba8f659578a31ed94149b1333 Mon Sep 17 00:00:00 2001 From: Ella Date: Tue, 7 May 2024 11:35:36 +0900 Subject: [PATCH 2/6] Separate file --- .../block-list/use-block-props/index.js | 26 ++--------------- .../use-block-props/use-scroll-into-view.js | 29 +++++++++++++++++++ 2 files changed, 32 insertions(+), 23 deletions(-) create mode 100644 packages/block-editor/src/components/block-list/use-block-props/use-scroll-into-view.js diff --git a/packages/block-editor/src/components/block-list/use-block-props/index.js b/packages/block-editor/src/components/block-list/use-block-props/index.js index b263c2086b12b..64e40559bb473 100644 --- a/packages/block-editor/src/components/block-list/use-block-props/index.js +++ b/packages/block-editor/src/components/block-list/use-block-props/index.js @@ -9,7 +9,7 @@ import clsx from 'clsx'; import { useContext } from '@wordpress/element'; import { __, sprintf } from '@wordpress/i18n'; import { __unstableGetBlockProps as getBlockProps } from '@wordpress/blocks'; -import { useMergeRefs, useDisabled, useRefEffect } from '@wordpress/compose'; +import { useMergeRefs, useDisabled } from '@wordpress/compose'; import warning from '@wordpress/warning'; /** @@ -28,6 +28,7 @@ import { useEventHandlers } from './use-selected-block-event-handlers'; import { useNavModeExit } from './use-nav-mode-exit'; import { useBlockRefProvider } from './use-block-refs'; import { useIntersectionObserver } from './use-intersection-observer'; +import { useScrollIntoView } from './use-scroll-into-view'; import { useFlashEditableBlocks } from '../../use-flash-editable-blocks'; import { canBindBlock } from '../../../hooks/use-bindings-attributes'; @@ -122,28 +123,7 @@ export function useBlockProps( props = {}, { __unstableIsHtml } = {} ) { clientId, isEnabled: name === 'core/block' || templateLock === 'contentOnly', } ), - useRefEffect( - ( node ) => { - if ( isSelected ) { - const { defaultView } = node.ownerDocument; - const observer = new defaultView.IntersectionObserver( - ( entries ) => { - // Once observing starts, we always get an initial - // entry with the intersecting state. - if ( ! entries[ 0 ].isIntersecting ) { - node.scrollIntoView(); - observer.disconnect(); - } - } - ); - observer.observe( node ); - return () => { - observer.disconnect(); - }; - } - }, - [ isSelected ] - ), + useScrollIntoView( { isSelected } ), ] ); const blockEditContext = useBlockEditContext(); diff --git a/packages/block-editor/src/components/block-list/use-block-props/use-scroll-into-view.js b/packages/block-editor/src/components/block-list/use-block-props/use-scroll-into-view.js new file mode 100644 index 0000000000000..207bfb6c22a27 --- /dev/null +++ b/packages/block-editor/src/components/block-list/use-block-props/use-scroll-into-view.js @@ -0,0 +1,29 @@ +/** + * WordPress dependencies + */ +import { useRefEffect } from '@wordpress/compose'; + +export function useScrollIntoView( { isSelected } ) { + return useRefEffect( + ( node ) => { + if ( isSelected ) { + const { defaultView } = node.ownerDocument; + const observer = new defaultView.IntersectionObserver( + ( entries ) => { + // Once observing starts, we always get an initial + // entry with the intersecting state. + if ( ! entries[ 0 ].isIntersecting ) { + node.scrollIntoView(); + observer.disconnect(); + } + } + ); + observer.observe( node ); + return () => { + observer.disconnect(); + }; + } + }, + [ isSelected ] + ); +} From bbb1286df26f3ab4b3d93f7b2b7a64ccada9a1e1 Mon Sep 17 00:00:00 2001 From: Ella Date: Tue, 7 May 2024 11:46:12 +0900 Subject: [PATCH 3/6] Fix unit test errors --- .../block-list/use-block-props/use-scroll-into-view.js | 6 +++++- packages/block-editor/src/store/selectors.js | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/block-editor/src/components/block-list/use-block-props/use-scroll-into-view.js b/packages/block-editor/src/components/block-list/use-block-props/use-scroll-into-view.js index 207bfb6c22a27..51d924e9bf777 100644 --- a/packages/block-editor/src/components/block-list/use-block-props/use-scroll-into-view.js +++ b/packages/block-editor/src/components/block-list/use-block-props/use-scroll-into-view.js @@ -7,7 +7,11 @@ export function useScrollIntoView( { isSelected } ) { return useRefEffect( ( node ) => { if ( isSelected ) { - const { defaultView } = node.ownerDocument; + const { ownerDocument } = node; + const { defaultView } = ownerDocument; + if ( ! defaultView ) { + return; + } const observer = new defaultView.IntersectionObserver( ( entries ) => { // Once observing starts, we always get an initial diff --git a/packages/block-editor/src/store/selectors.js b/packages/block-editor/src/store/selectors.js index 0d6c4e921594b..4ce85afb8cfd1 100644 --- a/packages/block-editor/src/store/selectors.js +++ b/packages/block-editor/src/store/selectors.js @@ -2751,7 +2751,7 @@ export function wasBlockJustInserted( state, clientId, source ) { * @return {boolean} True if the block is visible. */ export function isBlockVisible( state, clientId ) { - return state.blockVisibility?.[ clientId ]; + return state.blockVisibility?.[ clientId ] ?? true; } /** From 8543cfde9070daf28d24336ae3af261d96976733 Mon Sep 17 00:00:00 2001 From: Ella Date: Tue, 7 May 2024 16:40:09 +0900 Subject: [PATCH 4/6] Try fixing unit tests again --- .../block-list/use-block-props/use-scroll-into-view.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/block-editor/src/components/block-list/use-block-props/use-scroll-into-view.js b/packages/block-editor/src/components/block-list/use-block-props/use-scroll-into-view.js index 51d924e9bf777..32007970d5bd7 100644 --- a/packages/block-editor/src/components/block-list/use-block-props/use-scroll-into-view.js +++ b/packages/block-editor/src/components/block-list/use-block-props/use-scroll-into-view.js @@ -9,7 +9,7 @@ export function useScrollIntoView( { isSelected } ) { if ( isSelected ) { const { ownerDocument } = node; const { defaultView } = ownerDocument; - if ( ! defaultView ) { + if ( ! defaultView.IntersectionObserver ) { return; } const observer = new defaultView.IntersectionObserver( From e20cff22afc49fac5bf7a2009d3451693af09ab2 Mon Sep 17 00:00:00 2001 From: Andrei Draganescu Date: Wed, 8 May 2024 10:45:57 +0900 Subject: [PATCH 5/6] animate scrolling if reduced motion is off --- .../block-list/use-block-props/use-scroll-into-view.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/packages/block-editor/src/components/block-list/use-block-props/use-scroll-into-view.js b/packages/block-editor/src/components/block-list/use-block-props/use-scroll-into-view.js index 32007970d5bd7..ec210bc6f2eb9 100644 --- a/packages/block-editor/src/components/block-list/use-block-props/use-scroll-into-view.js +++ b/packages/block-editor/src/components/block-list/use-block-props/use-scroll-into-view.js @@ -1,9 +1,10 @@ /** * WordPress dependencies */ -import { useRefEffect } from '@wordpress/compose'; +import { useReducedMotion, useRefEffect } from '@wordpress/compose'; export function useScrollIntoView( { isSelected } ) { + const prefersReducedMotion = useReducedMotion(); return useRefEffect( ( node ) => { if ( isSelected ) { @@ -17,7 +18,11 @@ export function useScrollIntoView( { isSelected } ) { // Once observing starts, we always get an initial // entry with the intersecting state. if ( ! entries[ 0 ].isIntersecting ) { - node.scrollIntoView(); + node.scrollIntoView( { + behavior: prefersReducedMotion + ? 'instant' + : 'smooth', + } ); observer.disconnect(); } } From d32b351cf83ec18df078090322c9ca988dd74312 Mon Sep 17 00:00:00 2001 From: Andrei Draganescu Date: Wed, 8 May 2024 11:14:03 +0900 Subject: [PATCH 6/6] fix sticky scroll --- .../block-list/use-block-props/use-scroll-into-view.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/block-editor/src/components/block-list/use-block-props/use-scroll-into-view.js b/packages/block-editor/src/components/block-list/use-block-props/use-scroll-into-view.js index ec210bc6f2eb9..6301dac2c2108 100644 --- a/packages/block-editor/src/components/block-list/use-block-props/use-scroll-into-view.js +++ b/packages/block-editor/src/components/block-list/use-block-props/use-scroll-into-view.js @@ -23,8 +23,8 @@ export function useScrollIntoView( { isSelected } ) { ? 'instant' : 'smooth', } ); - observer.disconnect(); } + observer.disconnect(); } ); observer.observe( node );