Skip to content

Commit

Permalink
Switching pattern categories inserter to Tabs component with arrow ke…
Browse files Browse the repository at this point in the history
…y navigation (#60257)

Patterns categories are now using the tabs component so they are one tab stop. Arrow keys are used to move between the categories.

Co-authored-by: jeryj <jeryj@git.wordpress.org>
Co-authored-by: draganescu <andraganescu@git.wordpress.org>
Co-authored-by: scruffian <scruffian@git.wordpress.org>
Co-authored-by: getdave <get_dave@git.wordpress.org>
Co-authored-by: jameskoster <jameskoster@git.wordpress.org>
Co-authored-by: alexstine <alexstine@git.wordpress.org>
  • Loading branch information
7 people committed Apr 19, 2024
1 parent ff3afd3 commit dcbccfb
Show file tree
Hide file tree
Showing 11 changed files with 214 additions and 173 deletions.
4 changes: 4 additions & 0 deletions packages/block-editor/README.md
Expand Up @@ -1032,6 +1032,10 @@ _Returns_

A hook used to set the editor mode to zoomed out mode, invoking the hook sets the mode.

_Parameters_

- _zoomOut_ `boolean`: If we should enter into zoomOut mode or not

### Warning

_Related_
Expand Down
Expand Up @@ -5,11 +5,10 @@ import { useState } from '@wordpress/element';
import { __, isRTL } from '@wordpress/i18n';
import { useViewportMatch } from '@wordpress/compose';
import {
__experimentalItemGroup as ItemGroup,
__experimentalItem as Item,
__experimentalHStack as HStack,
FlexBlock,
Button,
privateApis as componentsPrivateApis,
} from '@wordpress/components';
import { Icon, chevronRight, chevronLeft } from '@wordpress/icons';

Expand All @@ -20,41 +19,48 @@ import PatternsExplorerModal from '../block-patterns-explorer';
import MobileTabNavigation from '../mobile-tab-navigation';
import { PatternCategoryPreviews } from './pattern-category-previews';
import { usePatternCategories } from './use-pattern-categories';
import { unlock } from '../../../lock-unlock';

const { Tabs } = unlock( componentsPrivateApis );

function BlockPatternsTab( {
onSelectCategory,
selectedCategory,
onInsert,
rootClientId,
children,
} ) {
const [ showPatternsExplorer, setShowPatternsExplorer ] = useState( false );

const categories = usePatternCategories( rootClientId );

const initialCategory = selectedCategory || categories[ 0 ];
const isMobile = useViewportMatch( 'medium', '<' );

return (
<>
{ ! isMobile && (
<div className="block-editor-inserter__block-patterns-tabs-container">
<nav
aria-label={ __( 'Block pattern categories' ) }
className="block-editor-inserter__block-patterns-tabs"
<Tabs
selectOnMove={ false }
selectedTabId={
selectedCategory ? selectedCategory.name : null
}
orientation={ 'vertical' }
onSelect={ ( categoryId ) => {
// Pass the full category object
onSelectCategory(
categories.find(
( category ) => category.name === categoryId
)
);
} }
>
<ItemGroup role="list">
<Tabs.TabList className="block-editor-inserter__block-patterns-tablist">
{ categories.map( ( category ) => (
<Item
role="listitem"
<Tabs.Tab
key={ category.name }
onClick={ () =>
onSelectCategory( category )
}
className={
category === selectedCategory
? 'block-editor-inserter__patterns-category block-editor-inserter__patterns-selected-category'
: 'block-editor-inserter__patterns-category'
}
tabId={ category.name }
className="block-editor-inserter__patterns-tab"
aria-label={ category.label }
aria-current={
category === selectedCategory
Expand All @@ -74,39 +80,47 @@ function BlockPatternsTab( {
}
/>
</HStack>
</Item>
</Tabs.Tab>
) ) }
<div role="listitem">
<Button
className="block-editor-inserter__patterns-explore-button"
onClick={ () =>
setShowPatternsExplorer( true )
}
variant="secondary"
>
{ __( 'Explore all patterns' ) }
</Button>
</div>
</ItemGroup>
</nav>
</Tabs.TabList>
{ categories.map( ( category ) => (
<Tabs.TabPanel
key={ category.name }
tabId={ category.name }
focusable={ false }
className="block-editor-inserter__patterns-category-panel"
>
{ children }
</Tabs.TabPanel>
) ) }
</Tabs>
<Button
className="block-editor-inserter__patterns-explore-button"
onClick={ () => setShowPatternsExplorer( true ) }
variant="secondary"
>
{ __( 'Explore all patterns' ) }
</Button>
</div>
) }
{ isMobile && (
<MobileTabNavigation categories={ categories }>
{ ( category ) => (
<PatternCategoryPreviews
key={ category.name }
onInsert={ onInsert }
rootClientId={ rootClientId }
category={ category }
showTitlesAsTooltip={ false }
/>
<div className="block-editor-inserter__patterns-category-panel">
<PatternCategoryPreviews
key={ category.name }
onInsert={ onInsert }
rootClientId={ rootClientId }
category={ category }
showTitlesAsTooltip={ false }
/>
</div>
) }
</MobileTabNavigation>
) }
{ showPatternsExplorer && (
<PatternsExplorerModal
initialCategory={ initialCategory }
initialCategory={ selectedCategory || categories[ 0 ] }
patternCategories={ categories }
onModalClose={ () => setShowPatternsExplorer( false ) }
rootClientId={ rootClientId }
Expand Down
@@ -1,16 +1,8 @@
/**
* WordPress dependencies
*/
import { useRef, useEffect } from '@wordpress/element';

import { focus } from '@wordpress/dom';

/**
* Internal dependencies
*/

import { PatternCategoryPreviews } from './pattern-category-previews';
import { useZoomOut } from '../../../hooks/use-zoom-out';

export function PatternCategoryPreviewPanel( {
rootClientId,
Expand All @@ -20,34 +12,15 @@ export function PatternCategoryPreviewPanel( {
showTitlesAsTooltip,
patternFilter,
} ) {
const container = useRef();

useEffect( () => {
const timeout = setTimeout( () => {
const [ firstTabbable ] = focus.tabbable.find( container.current );
firstTabbable?.focus();
} );
return () => clearTimeout( timeout );
}, [ category ] );

// Move to zoom out mode when this component is mounted
// and back to the previous mode when unmounted.
useZoomOut();

return (
<div
ref={ container }
className="block-editor-inserter__patterns-category-dialog"
>
<PatternCategoryPreviews
key={ category.name }
rootClientId={ rootClientId }
onInsert={ onInsert }
onHover={ onHover }
category={ category }
showTitlesAsTooltip={ showTitlesAsTooltip }
patternFilter={ patternFilter }
/>
</div>
<PatternCategoryPreviews
key={ category.name }
rootClientId={ rootClientId }
onInsert={ onInsert }
onHover={ onHover }
category={ category }
showTitlesAsTooltip={ showTitlesAsTooltip }
patternFilter={ patternFilter }
/>
);
}
Expand Up @@ -128,7 +128,7 @@ export function PatternCategoryPreviews( {
);

return (
<div className="block-editor-inserter__patterns-category-panel">
<>
<VStack
spacing={ 2 }
className="block-editor-inserter__patterns-category-panel-header"
Expand Down Expand Up @@ -174,6 +174,6 @@ export function PatternCategoryPreviews( {
pagingProps={ pagingProps }
/>
) }
</div>
</>
);
}
43 changes: 27 additions & 16 deletions packages/block-editor/src/components/inserter/menu.js
Expand Up @@ -33,6 +33,7 @@ import InserterSearchResults from './search-results';
import useInsertionPoint from './hooks/use-insertion-point';
import InserterTabs from './tabs';
import { store as blockEditorStore } from '../../store';
import { useZoomOut } from '../../hooks/use-zoom-out';

const NOOP = () => {};
function InserterMenu(
Expand Down Expand Up @@ -125,6 +126,11 @@ function InserterMenu(
[ setSelectedPatternCategory, __experimentalOnPatternCategorySelection ]
);

const showPatternPanel =
selectedTab === 'patterns' &&
! delayedFilterValue &&
selectedPatternCategory;

const blocksTab = useMemo(
() => (
<>
Expand Down Expand Up @@ -162,13 +168,25 @@ function InserterMenu(
onInsert={ onInsertPattern }
onSelectCategory={ onClickPatternCategory }
selectedCategory={ selectedPatternCategory }
/>
>
{ showPatternPanel && (
<PatternCategoryPreviewPanel
rootClientId={ destinationRootClientId }
onInsert={ onInsertPattern }
onHover={ onHoverPattern }
category={ selectedPatternCategory }
patternFilter={ patternFilter }
showTitlesAsTooltip
/>
) }
</BlockPatternsTab>
),
[
destinationRootClientId,
onInsertPattern,
onClickPatternCategory,
selectedPatternCategory,
showPatternPanel,
]
);

Expand Down Expand Up @@ -205,16 +223,15 @@ function InserterMenu(
},
} ) );

const showPatternPanel =
selectedTab === 'patterns' &&
! delayedFilterValue &&
selectedPatternCategory;
const showAsTabs = ! delayedFilterValue && ( showPatterns || showMedia );
const showMediaPanel =
selectedTab === 'media' &&
! delayedFilterValue &&
selectedMediaCategory;

// When the pattern panel is showing, we want to use zoom out mode
useZoomOut( showPatternPanel );

const handleSetSelectedTab = ( value ) => {
// If no longer on patterns tab remove the category setting.
if ( value !== 'patterns' ) {
Expand All @@ -224,7 +241,11 @@ function InserterMenu(
};

return (
<div className="block-editor-inserter__menu">
<div
className={ classnames( 'block-editor-inserter__menu', {
'show-panel': showPatternPanel,
} ) }
>
<div
className={ classnames( 'block-editor-inserter__main-area', {
'show-as-tabs': showAsTabs,
Expand Down Expand Up @@ -292,16 +313,6 @@ function InserterMenu(
<InserterPreviewPanel item={ hoveredItem } />
</Popover>
) }
{ showPatternPanel && (
<PatternCategoryPreviewPanel
rootClientId={ destinationRootClientId }
onInsert={ onInsertPattern }
onHover={ onHoverPattern }
category={ selectedPatternCategory }
patternFilter={ patternFilter }
showTitlesAsTooltip
/>
) }
</div>
);
}
Expand Down

0 comments on commit dcbccfb

Please sign in to comment.