diff --git a/packages/block-editor/src/components/block-manager/category.js b/packages/block-editor/src/components/block-manager/category.js index c447eec5797f52..22914c4f2b1ab0 100644 --- a/packages/block-editor/src/components/block-manager/category.js +++ b/packages/block-editor/src/components/block-manager/category.js @@ -1,7 +1,7 @@ /** * WordPress dependencies */ -import { useCallback, forwardRef } from '@wordpress/element'; +import { useCallback } from '@wordpress/element'; import { useInstanceId } from '@wordpress/compose'; import { CheckboxControl } from '@wordpress/components'; @@ -9,97 +9,94 @@ import { CheckboxControl } from '@wordpress/components'; * Internal dependencies */ import BlockTypesChecklist from './checklist'; -const a = forwardRef( () => { - return a; -} ); -const BlockManagerCategory = forwardRef( - ( { title, blockTypes, selectedBlockTypes, onChange }, ref ) => { - const instanceId = useInstanceId( BlockManagerCategory ); +const BlockManagerCategory = ( { + title, + blockTypes, + selectedBlockTypes, + onChange, +} ) => { + const instanceId = useInstanceId( BlockManagerCategory ); - const toggleVisible = useCallback( - ( blockType, nextIsChecked ) => { - if ( nextIsChecked ) { - onChange( [ ...selectedBlockTypes, blockType ] ); - } else { - onChange( - selectedBlockTypes.filter( - ( { name } ) => name !== blockType.name - ) - ); - } - }, - [ selectedBlockTypes, onChange ] - ); + const toggleVisible = useCallback( + ( blockType, nextIsChecked ) => { + if ( nextIsChecked ) { + onChange( [ ...selectedBlockTypes, blockType ] ); + } else { + onChange( + selectedBlockTypes.filter( + ( { name } ) => name !== blockType.name + ) + ); + } + }, + [ selectedBlockTypes, onChange ] + ); - const toggleAllVisible = useCallback( - ( nextIsChecked ) => { - if ( nextIsChecked ) { - onChange( [ - ...selectedBlockTypes, - ...blockTypes.filter( - ( blockType ) => - ! selectedBlockTypes.find( - ( { name } ) => name === blockType.name - ) - ), - ] ); - } else { - onChange( - selectedBlockTypes.filter( - ( selectedBlockType ) => - ! blockTypes.find( - ( { name } ) => - name === selectedBlockType.name - ) - ) - ); - } - }, - [ blockTypes, selectedBlockTypes, onChange ] - ); + const toggleAllVisible = useCallback( + ( nextIsChecked ) => { + if ( nextIsChecked ) { + onChange( [ + ...selectedBlockTypes, + ...blockTypes.filter( + ( blockType ) => + ! selectedBlockTypes.find( + ( { name } ) => name === blockType.name + ) + ), + ] ); + } else { + onChange( + selectedBlockTypes.filter( + ( selectedBlockType ) => + ! blockTypes.find( + ( { name } ) => name === selectedBlockType.name + ) + ) + ); + } + }, + [ blockTypes, selectedBlockTypes, onChange ] + ); - if ( ! blockTypes.length ) { - return null; - } + if ( ! blockTypes.length ) { + return null; + } - const checkedBlockNames = blockTypes - .map( ( { name } ) => name ) - .filter( ( type ) => - ( selectedBlockTypes ?? [] ).some( - ( selectedBlockType ) => selectedBlockType.name === type - ) - ); + const checkedBlockNames = blockTypes + .map( ( { name } ) => name ) + .filter( ( type ) => + ( selectedBlockTypes ?? [] ).some( + ( selectedBlockType ) => selectedBlockType.name === type + ) + ); - const titleId = - 'block-editor-block-manager__category-title-' + instanceId; + const titleId = 'block-editor-block-manager__category-title-' + instanceId; - const isAllChecked = checkedBlockNames.length === blockTypes.length; - const isIndeterminate = ! isAllChecked && checkedBlockNames.length > 0; + const isAllChecked = checkedBlockNames.length === blockTypes.length; + const isIndeterminate = ! isAllChecked && checkedBlockNames.length > 0; - return ( -
- { title } } - /> - -
- ); - } -); + return ( +
+ { title } } + /> + +
+ ); +}; export default BlockManagerCategory; diff --git a/packages/block-editor/src/components/block-manager/index.js b/packages/block-editor/src/components/block-manager/index.js index c9a8993673191e..2fdade776f8ddd 100644 --- a/packages/block-editor/src/components/block-manager/index.js +++ b/packages/block-editor/src/components/block-manager/index.js @@ -5,7 +5,7 @@ import { store as blocksStore } from '@wordpress/blocks'; import { useSelect } from '@wordpress/data'; import { SearchControl, Button } from '@wordpress/components'; import { __, _n, sprintf } from '@wordpress/i18n'; -import { useEffect, useState, useRef } from '@wordpress/element'; +import { useEffect, useState } from '@wordpress/element'; import { useDebounce } from '@wordpress/compose'; import { speak } from '@wordpress/a11y'; @@ -35,33 +35,50 @@ export default function BlockManager( { isMatchingSearchTerm: select( blocksStore ).isMatchingSearchTerm, }; }, [] ); - const blockManagerCategoryRef = useRef( null ); + + // Function to determine which sticky element is active in the viewport + const getActiveStickyElement = ( Elements, parentElement ) => { + for ( const Element of Elements ) { + const rect = Element.getBoundingClientRect(); + + // Check if the sticky element is in the viewport + if ( rect.top < parentElement.clientHeight && rect.bottom > 0 ) { + return Element; // Return the active sticky element + } + } + return null; // No sticky element is active in the viewport + }; useEffect( () => { const container = document.querySelector( '.components-modal__content' ); - const stickyElement = blockManagerCategoryRef.current; + const stickyElements = document.querySelectorAll( + '.block-editor-block-manager__category-title' + ); + let activeStickyElement = null; - if ( ! container || ! stickyElement ) { + if ( ! container || ! stickyElements ) { return; } const handleFocusIn = ( event ) => { + activeStickyElement = getActiveStickyElement( + stickyElements, + container + ); const focusedElement = event.target; // Check if the focused element is within the container if ( container.contains( focusedElement ) ) { - const stickyBottom = 250; + const stickyBottom = + activeStickyElement.getBoundingClientRect().bottom; const focusedRect = focusedElement.getBoundingClientRect(); // Calculate the desired scroll position - if ( - focusedRect.top < stickyBottom && - container.scrollTop > 190 - ) { + if ( focusedRect.top < stickyBottom ) { const offset = - container.scrollTop - stickyElement.offsetHeight; + container.scrollTop - activeStickyElement.offsetHeight; container.scrollTo( { top: offset, behavior: 'smooth', @@ -145,7 +162,6 @@ export default function BlockManager( { ) } { categories.map( ( category ) => ( ) ) } ! category