Skip to content

Commit

Permalink
[Patterns] Separate sync status into a filter control (#52303)
Browse files Browse the repository at this point in the history
Co-authored-by: Saxon Fletcher <saxonafletcher@gmail.com>
Co-authored-by: Glen Davies <glen.davies@automattic.com>
  • Loading branch information
3 people authored and tellthemachines committed Jul 10, 2023
1 parent cfcf5ff commit 509fcf3
Show file tree
Hide file tree
Showing 8 changed files with 372 additions and 271 deletions.
22 changes: 14 additions & 8 deletions packages/edit-site/src/components/page-patterns/grid-item.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,14 @@ import {
Flex,
} from '@wordpress/components';
import { useDispatch } from '@wordpress/data';
import { useState, useId } from '@wordpress/element';
import { useState, useId, memo } from '@wordpress/element';
import { __, sprintf } from '@wordpress/i18n';
import {
Icon,
header,
footer,
symbolFilled as uncategorized,
symbol,
moreHorizontal,
lockSmall,
} from '@wordpress/icons';
Expand All @@ -38,13 +39,13 @@ import { DELETE, BACKSPACE } from '@wordpress/keycodes';
*/
import RenameMenuItem from './rename-menu-item';
import DuplicateMenuItem from './duplicate-menu-item';
import { PATTERNS, TEMPLATE_PARTS, USER_PATTERNS } from './utils';
import { PATTERNS, TEMPLATE_PARTS, USER_PATTERNS, SYNC_TYPES } from './utils';
import { store as editSiteStore } from '../../store';
import { useLink } from '../routes/link';

const templatePartIcons = { header, footer, uncategorized };

export default function GridItem( { categoryId, composite, icon, item } ) {
function GridItem( { categoryId, item, ...props } ) {
const descriptionId = useId();
const [ isDeleteDialogOpen, setIsDeleteDialogOpen ] = useState( false );

Expand Down Expand Up @@ -123,9 +124,9 @@ export default function GridItem( { categoryId, composite, icon, item } ) {
ariaDescriptions.push( __( 'Theme patterns cannot be edited.' ) );
}

const itemIcon = templatePartIcons[ categoryId ]
? templatePartIcons[ categoryId ]
: icon;
const itemIcon =
templatePartIcons[ categoryId ] ||
( item.syncStatus === SYNC_TYPES.full ? symbol : undefined );

const confirmButtonText = hasThemeFile ? __( 'Clear' ) : __( 'Delete' );
const confirmPrompt = hasThemeFile
Expand All @@ -143,7 +144,10 @@ export default function GridItem( { categoryId, composite, icon, item } ) {
className={ previewClassNames }
role="option"
as="div"
{ ...composite }
// Even though still incomplete, passing ids helps performance.
// @see https://reakit.io/docs/composite/#performance.
id={ `edit-site-patterns-${ item.name }` }
{ ...props }
onClick={ item.type !== PATTERNS ? onClick : undefined }
onKeyDown={ isCustomPattern ? onKeyDown : undefined }
aria-label={ item.title }
Expand Down Expand Up @@ -181,7 +185,7 @@ export default function GridItem( { categoryId, composite, icon, item } ) {
spacing={ 3 }
className="edit-site-patterns__pattern-title"
>
{ icon && (
{ itemIcon && (
<Icon
className="edit-site-patterns__pattern-icon"
icon={ itemIcon }
Expand Down Expand Up @@ -274,3 +278,5 @@ export default function GridItem( { categoryId, composite, icon, item } ) {
</>
);
}

export default memo( GridItem );
56 changes: 38 additions & 18 deletions packages/edit-site/src/components/page-patterns/grid.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,36 +4,56 @@
import {
__unstableComposite as Composite,
__unstableUseCompositeState as useCompositeState,
__experimentalText as Text,
} from '@wordpress/components';
import { useRef } from '@wordpress/element';
import { __, sprintf } from '@wordpress/i18n';

/**
* Internal dependencies
*/
import GridItem from './grid-item';

export default function Grid( { categoryId, label, icon, items } ) {
const composite = useCompositeState( { orientation: 'vertical' } );
const PAGE_SIZE = 100;

export default function Grid( { categoryId, items, ...props } ) {
const composite = useCompositeState( { wrap: true } );
const gridRef = useRef();

if ( ! items?.length ) {
return null;
}

const list = items.slice( 0, PAGE_SIZE );
const restLength = items.length - PAGE_SIZE;

return (
<Composite
{ ...composite }
role="listbox"
className="edit-site-patterns__grid"
aria-label={ label }
>
{ items.map( ( item ) => (
<GridItem
key={ item.name }
icon={ icon }
item={ item }
categoryId={ categoryId }
composite={ composite }
/>
) ) }
</Composite>
<>
<Composite
{ ...composite }
role="listbox"
className="edit-site-patterns__grid"
{ ...props }
ref={ gridRef }
>
{ list.map( ( item ) => (
<GridItem
key={ item.name }
item={ item }
categoryId={ categoryId }
{ ...composite }
/>
) ) }
</Composite>
{ restLength > 0 && (
<Text variant="muted" as="p" align="center">
{ sprintf(
/* translators: %d: number of patterns */
__( '+ %d more patterns discoverable by searching' ),
restLength
) }
</Text>
) }
</>
);
}
69 changes: 69 additions & 0 deletions packages/edit-site/src/components/page-patterns/header.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/**
* WordPress dependencies
*/
import {
__experimentalVStack as VStack,
__experimentalHeading as Heading,
__experimentalText as Text,
} from '@wordpress/components';
import { __ } from '@wordpress/i18n';
import { store as editorStore } from '@wordpress/editor';
import { useSelect } from '@wordpress/data';

/**
* Internal dependencies
*/
import usePatternCategories from '../sidebar-navigation-screen-patterns/use-pattern-categories';
import {
USER_PATTERN_CATEGORY,
USER_PATTERNS,
TEMPLATE_PARTS,
PATTERNS,
} from './utils';

export default function PatternsHeader( {
categoryId,
type,
titleId,
descriptionId,
} ) {
const { patternCategories } = usePatternCategories();
const templatePartAreas = useSelect(
( select ) =>
select( editorStore ).__experimentalGetDefaultTemplatePartAreas(),
[]
);

let title, description;
if ( categoryId === USER_PATTERN_CATEGORY && type === USER_PATTERNS ) {
title = __( 'My Patterns' );
description = '';
} else if ( type === TEMPLATE_PARTS ) {
const templatePartArea = templatePartAreas.find(
( area ) => area.area === categoryId
);
title = templatePartArea?.label;
description = templatePartArea?.description;
} else if ( type === PATTERNS ) {
const patternCategory = patternCategories.find(
( category ) => category.name === categoryId
);
title = patternCategory?.label;
description = patternCategory?.description;
}

if ( ! title ) return null;

return (
<VStack className="edit-site-patterns__section-header">
<Heading as="h2" level={ 4 } id={ titleId }>
{ title }
</Heading>
{ description ? (
<Text variant="muted" as="p" id={ descriptionId }>
{ description }
</Text>
) : null }
</VStack>
);
}
7 changes: 6 additions & 1 deletion packages/edit-site/src/components/page-patterns/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,12 @@ export default function PagePatterns() {
title={ __( 'Patterns content' ) }
hideTitleFromUI
>
<PatternsList type={ type } categoryId={ category } />
<PatternsList
// Reset the states when switching between categories and types.
key={ `${ type }-${ category }` }
type={ type }
categoryId={ category }
/>
</Page>
</ExperimentalBlockEditorProvider>
);
Expand Down

0 comments on commit 509fcf3

Please sign in to comment.