Skip to content

Commit

Permalink
Block props: reduce memoized context (#29183)
Browse files Browse the repository at this point in the history
* Block props: reduce memoized context

* merge select

* Reduce further
  • Loading branch information
ellatrix committed Feb 21, 2021
1 parent 96ac9d5 commit 80bed43
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 74 deletions.
17 changes: 0 additions & 17 deletions packages/block-editor/src/components/block-list/block.js
Expand Up @@ -87,9 +87,6 @@ function BlockListBlock( {
clientId,
isSelected,
isMultiSelected,
isPartOfMultiSelection,
isFirstMultiSelected,
isLastMultiSelected,
isTypingWithinBlock,
isAncestorOfSelectedBlock,
isSelectionEnabled,
Expand All @@ -104,7 +101,6 @@ function BlockListBlock( {
onMerge,
toggleSelection,
index,
enableAnimation,
activeEntityBlockId,
} ) {
const isLargeViewport = useViewportMatch( 'medium' );
Expand Down Expand Up @@ -219,15 +215,8 @@ function BlockListBlock( {
const value = {
clientId,
isSelected,
isFirstMultiSelected,
isLastMultiSelected,
isPartOfMultiSelection,
enableAnimation,
index,
className: wrapperClassName,
isLocked,
name,
blockTitle: blockType.title,
wrapperProps: omit( wrapperProps, [ 'data-align' ] ),
};
const memoizedValue = useMemo( () => value, Object.values( value ) );
Expand Down Expand Up @@ -275,10 +264,8 @@ function BlockListBlock( {
const applyWithSelect = withSelect( ( select, { clientId, rootClientId } ) => {
const {
isBlockSelected,
isAncestorMultiSelected,
isBlockMultiSelected,
isFirstMultiSelectedBlock,
getLastMultiSelectedBlockClientId,
isTyping,
getBlockMode,
isSelectionEnabled,
Expand Down Expand Up @@ -309,11 +296,7 @@ const applyWithSelect = withSelect( ( select, { clientId, rootClientId } ) => {
// leaking new props to the public API (editor.BlockListBlock filter).
return {
isMultiSelected: isBlockMultiSelected( clientId ),
isPartOfMultiSelection:
isBlockMultiSelected( clientId ) ||
isAncestorMultiSelected( clientId ),
isFirstMultiSelected,
isLastMultiSelected: getLastMultiSelectedBlockClientId() === clientId,
multiSelectedClientIds: isFirstMultiSelected
? getMultiSelectedBlockClientIds()
: undefined,
Expand Down
13 changes: 0 additions & 13 deletions packages/block-editor/src/components/block-list/index.js
Expand Up @@ -20,12 +20,6 @@ import BlockPopover from './block-popover';
import { store as blockEditorStore } from '../../store';
import { useScrollSelectionIntoView } from '../selection-scroll-into-view';

/**
* If the block count exceeds the threshold, we disable the reordering animation
* to avoid laginess.
*/
const BLOCK_ANIMATION_THRESHOLD = 200;

export const BlockNodes = createContext();
export const SetBlockNodes = createContext();

Expand Down Expand Up @@ -69,8 +63,6 @@ function Items( {
getSelectedBlockClientId,
getMultiSelectedBlockClientIds,
hasMultiSelection,
getGlobalBlockCount,
isTyping,
__experimentalGetActiveBlockIdByBlockNames,
} = select( blockEditorStore );

Expand All @@ -85,9 +77,6 @@ function Items( {
multiSelectedBlockClientIds: getMultiSelectedBlockClientIds(),
orientation: getBlockListSettings( rootClientId )?.orientation,
hasMultiSelection: hasMultiSelection(),
enableAnimation:
! isTyping() &&
getGlobalBlockCount() <= BLOCK_ANIMATION_THRESHOLD,
activeEntityBlockId,
};
}
Expand All @@ -98,7 +87,6 @@ function Items( {
multiSelectedBlockClientIds,
orientation,
hasMultiSelection,
enableAnimation,
activeEntityBlockId,
} = useSelect( selector, [ rootClientId ] );

Expand Down Expand Up @@ -130,7 +118,6 @@ function Items( {
// to avoid being impacted by the async mode
// otherwise there might be a small delay to trigger the animation.
index={ index }
enableAnimation={ enableAnimation }
className={ classnames( {
'is-drop-target': isDropTarget,
'is-dropping-horizontally':
Expand Down
Expand Up @@ -8,7 +8,10 @@ import classnames from 'classnames';
*/
import { useRef, useContext } from '@wordpress/element';
import { __, sprintf } from '@wordpress/i18n';
import { __unstableGetBlockProps as getBlockProps } from '@wordpress/blocks';
import {
__unstableGetBlockProps as getBlockProps,
getBlockType,
} from '@wordpress/blocks';
import { useMergeRefs } from '@wordpress/compose';
import { useSelect } from '@wordpress/data';

Expand All @@ -24,6 +27,12 @@ import { useEventHandlers } from './use-event-handlers';
import { useBlockNodes } from './use-block-nodes';
import { store as blockEditorStore } from '../../../store';

/**
* If the block count exceeds the threshold, we disable the reordering animation
* to avoid laginess.
*/
const BLOCK_ANIMATION_THRESHOLD = 200;

/**
* This hook is used to lightly mark an element as a block element. The element
* should be the outermost element of a block. Call this hook and pass the
Expand All @@ -43,43 +52,66 @@ import { store as blockEditorStore } from '../../../store';
export function useBlockProps( props = {}, { __unstableIsHtml } = {} ) {
const fallbackRef = useRef();
const ref = props.ref || fallbackRef;
const { clientId, index, className, wrapperProps = {} } = useContext(
BlockListBlockContext
);
const {
clientId,
isSelected,
isFirstMultiSelected,
isPartOfMultiSelection,
enableAnimation,
index,
className,
mode,
name,
blockTitle,
wrapperProps = {},
} = useContext( BlockListBlockContext );
const mode = useSelect( ( select ) => {
return select( blockEditorStore ).getBlockMode( clientId );
} );
isPartOfSelection,
adjustScrolling,
enableAnimation,
} = useSelect(
( select ) => {
const {
getBlockMode,
getBlockName,
isTyping,
getGlobalBlockCount,
isBlockSelected,
isBlockMultiSelected,
isAncestorMultiSelected,
isFirstMultiSelectedBlock,
} = select( blockEditorStore );
const isSelected = isBlockSelected( clientId );
const isPartOfMultiSelection =
isBlockMultiSelected( clientId ) ||
isAncestorMultiSelected( clientId );
const blockName = getBlockName( clientId );
return {
mode: getBlockMode( clientId ),
name: blockName,
blockTitle: getBlockType( blockName ).title,
isPartOfSelection: isSelected || isPartOfMultiSelection,
adjustScrolling:
isSelected || isFirstMultiSelectedBlock( clientId ),
enableAnimation:
! isTyping() &&
getGlobalBlockCount() <= BLOCK_ANIMATION_THRESHOLD,
};
},
[ clientId ]
);

// translators: %s: Type of block (i.e. Text, Image etc)
const blockLabel = sprintf( __( 'Block: %s' ), blockTitle );

useFocusFirstElement( ref, clientId );

// Block Reordering animation
useMovingAnimation(
ref,
isSelected || isPartOfMultiSelection,
isSelected || isFirstMultiSelected,
enableAnimation,
index
);

const blockMovingModeClassNames = useBlockMovingModeClassNames( clientId );
const htmlSuffix = mode === 'html' && ! __unstableIsHtml ? '-visual' : '';
const mergedRefs = useMergeRefs( [
ref,
useBlockNodes( clientId ),
useEventHandlers( clientId ),
useIsHovered(),
useMovingAnimation( {
isSelected: isPartOfSelection,
adjustScrolling,
enableAnimation,
triggerAnimationOnChange: index,
} ),
] );

return {
Expand Down
19 changes: 6 additions & 13 deletions packages/block-editor/src/components/block-navigation/leaf.js
Expand Up @@ -8,7 +8,6 @@ import classnames from 'classnames';
* WordPress dependencies
*/
import { __experimentalTreeGridRow as TreeGridRow } from '@wordpress/components';
import { useRef } from '@wordpress/element';

/**
* Internal dependencies
Expand All @@ -27,22 +26,16 @@ export default function BlockNavigationLeaf( {
path,
...props
} ) {
const wrapper = useRef( null );
const adjustScrolling = false;
const enableAnimation = true;
const animateOnChange = path.join( '_' );
const style = useMovingAnimation(
wrapper,
const ref = useMovingAnimation( {
isSelected,
adjustScrolling,
enableAnimation,
animateOnChange
);
adjustScrolling: false,
enableAnimation: true,
triggerAnimationOnChange: path.join( '_' ),
} );

return (
<AnimatedTreeGridRow
ref={ wrapper }
style={ style }
ref={ ref }
className={ classnames(
'block-editor-block-navigation-leaf',
className
Expand Down
21 changes: 12 additions & 9 deletions packages/block-editor/src/components/use-moving-animation/index.js
Expand Up @@ -11,6 +11,7 @@ import {
useLayoutEffect,
useReducer,
useMemo,
useRef,
} from '@wordpress/element';
import { useReducedMotion } from '@wordpress/compose';
import { getScrollContainer } from '@wordpress/dom';
Expand Down Expand Up @@ -41,19 +42,19 @@ const getAbsolutePosition = ( element ) => {
* - It uses the "resetAnimation" flag to reset the animation
* from the beginning in order to animate to the new destination point.
*
* @param {Object} ref Reference to the element to animate.
* @param {boolean} isSelected Whether it's the current block or not.
* @param {boolean} adjustScrolling Adjust the scroll position to the current block.
* @param {boolean} enableAnimation Enable/Disable animation.
* @param {*} triggerAnimationOnChange Variable used to trigger the animation if it changes.
* @param {Object} $1 Options
* @param {boolean} $1.isSelected Whether it's the current block or not.
* @param {boolean} $1.adjustScrolling Adjust the scroll position to the current block.
* @param {boolean} $1.enableAnimation Enable/Disable animation.
* @param {*} $1.triggerAnimationOnChange Variable used to trigger the animation if it changes.
*/
function useMovingAnimation(
ref,
function useMovingAnimation( {
isSelected,
adjustScrolling,
enableAnimation,
triggerAnimationOnChange
) {
triggerAnimationOnChange,
} ) {
const ref = useRef();
const prefersReducedMotion = useReducedMotion() || ! enableAnimation;
const [ triggeredAnimation, triggerAnimation ] = useReducer(
counterReducer,
Expand Down Expand Up @@ -163,6 +164,8 @@ function useMovingAnimation(
immediate: prefersReducedMotion,
onFrame,
} );

return ref;
}

export default useMovingAnimation;

0 comments on commit 80bed43

Please sign in to comment.