Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Patterns: Add user pattern categories to post editor inserter patterns tab #53933

Merged
39 changes: 32 additions & 7 deletions packages/block-editor/src/components/block-patterns-list/index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
/**
* External dependencies
*/
import classnames from 'classnames';

/**
* WordPress dependencies
*/
Expand All @@ -8,9 +13,11 @@ import {
__unstableUseCompositeState as useCompositeState,
__unstableCompositeItem as CompositeItem,
Tooltip,
__experimentalHStack as HStack,
} from '@wordpress/components';
import { useInstanceId } from '@wordpress/compose';
import { __ } from '@wordpress/i18n';
import { Icon, symbol } from '@wordpress/icons';

/**
* Internal dependencies
Expand Down Expand Up @@ -63,14 +70,20 @@ function BlockPattern( {
} }
>
<WithToolTip
showTooltip={ showTooltip }
showTooltip={ showTooltip && ! pattern.id }
title={ pattern.title }
>
<CompositeItem
role="option"
as="div"
{ ...composite }
className="block-editor-block-patterns-list__item"
className={ classnames(
'block-editor-block-patterns-list__item',
{
'block-editor-block-patterns-list__list-item-synced':
pattern.id && ! pattern.syncStatus,
}
) }
onClick={ () => {
onClick( pattern, blocks );
onHover?.( null );
Expand All @@ -91,11 +104,23 @@ function BlockPattern( {
blocks={ blocks }
viewportWidth={ viewportWidth }
/>
{ ! showTooltip && (
<div className="block-editor-block-patterns-list__item-title">
{ pattern.title }
</div>
) }

<HStack className="block-editor-patterns__pattern-details">
{ pattern.id && ! pattern.syncStatus && (
<div className="block-editor-patterns__pattern-icon-wrapper">
<Icon
className="block-editor-patterns__pattern-icon"
icon={ symbol }
/>
</div>
) }
{ ( ! showTooltip || pattern.id ) && (
<div className="block-editor-block-patterns-list__item-title">
{ pattern.title }
</div>
) }
</HStack>

{ !! pattern.description && (
<VisuallyHidden id={ descriptionId }>
{ pattern.description }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
min-height: 100px;
}

&[draggable="true"] .block-editor-block-preview__container {
&[draggable="true"] {
cursor: grab;
}
}
Expand All @@ -27,22 +27,39 @@
}

.block-editor-block-patterns-list__item-title {
padding-top: $grid-unit-10;
font-size: 12px;
text-align: center;
text-align: left;
flex-grow: 1;
}

&:hover .block-editor-block-preview__container {
box-shadow: 0 0 0 2px var(--wp-admin-theme-color);
box-shadow: 0 0 0 2px $gray-900;
}

&:focus .block-editor-block-preview__container {
@include button-style-outset__focus(var(--wp-admin-theme-color));
@include button-style-outset__focus($gray-900);
}

&.block-editor-block-patterns-list__list-item-synced {
&:hover,
&:focus {
.block-editor-block-preview__container {
box-shadow:
0 0 0 2px var(--wp-block-synced-color),
0 15px 25px rgb(0 0 0 / 7%);
}
}
}

.block-editor-patterns__pattern-details {
align-items: center;
margin-top: $grid-unit-10;
}

&:hover .block-editor-block-patterns-list__item-title,
&:focus .block-editor-block-patterns-list__item-title {
color: var(--wp-admin-theme-color);
.block-editor-patterns__pattern-icon-wrapper {
min-width: 24px;
height: 24px;
.block-editor-patterns__pattern-icon {
fill: var(--wp-block-synced-color);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
/**
* WordPress dependencies
*/
import {
__experimentalVStack as VStack,
__experimentalHStack as HStack,
__experimentalText as Text,
Button,
} from '@wordpress/components';
import { __, _x, _n, sprintf } from '@wordpress/i18n';

export default function Pagination( {
currentPage,
numPages,
changePage,
totalItems,
} ) {
return (
<VStack>
<Text variant="muted">
{
// translators: %s: Total number of patterns.
sprintf(
// translators: %s: Total number of patterns.
_n( '%s item', '%s items', totalItems ),
totalItems
)
}
</Text>
<HStack
expanded={ false }
spacing={ 3 }
justify="flex-start"
className="block-editor-patterns__grid-pagination"
>
<HStack
expanded={ false }
spacing={ 1 }
className="block-editor-patterns__grid-pagination-previous"
>
<Button
variant="tertiary"
onClick={ () => changePage( 1 ) }
disabled={ currentPage === 1 }
aria-label={ __( 'First page' ) }
>
<span>«</span>
</Button>
<Button
variant="tertiary"
onClick={ () => changePage( currentPage - 1 ) }
disabled={ currentPage === 1 }
aria-label={ __( 'Previous page' ) }
>
<span>‹</span>
</Button>
</HStack>
<Text variant="muted">
{ sprintf(
// translators: %1$s: Current page number, %2$s: Total number of pages.
_x( '%1$s of %2$s', 'paging' ),
currentPage,
numPages
) }
</Text>
<HStack
expanded={ false }
spacing={ 1 }
className="block-editor-patterns__grid-pagination-next"
>
<Button
variant="tertiary"
onClick={ () => changePage( currentPage + 1 ) }
disabled={ currentPage === numPages }
aria-label={ __( 'Next page' ) }
>
<span>›</span>
</Button>
<Button
variant="tertiary"
onClick={ () => changePage( numPages ) }
disabled={ currentPage === numPages }
aria-label={ __( 'Last page' ) }
size="default"
>
<span>»</span>
</Button>
</HStack>
</HStack>
</VStack>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
.block-editor-patterns__grid-pagination {
border-top: 1px solid $gray-800;
padding: $grid-unit-05;

.components-button.is-tertiary {
width: auto;
height: $button-size-compact;
justify-content: center;

&:disabled {
color: $gray-600;
background: none;
}

&:hover:not(:disabled) {
color: $white;
background-color: $gray-700;
}
}
}

.show-icon-labels {
.block-editor-patterns__grid-pagination {
flex-direction: column;
.block-editor-patterns__grid-pagination-previous,
.block-editor-patterns__grid-pagination-next {
flex-direction: column;
}
.components-button {
width: auto;
// Hide the button icons when labels are set to display...
span {
display: none;
}
// ... and display labels.
// Uses ::before as ::after is already used for active tab styling.
&::before {
content: attr(aria-label);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,33 +2,69 @@
* WordPress dependencies
*/
import { Modal } from '@wordpress/components';
import { useState } from '@wordpress/element';
import { useState, useEffect } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
import { useSelect } from '@wordpress/data';
import { usePrevious } from '@wordpress/compose';

/**
* Internal dependencies
*/
import PatternExplorerSidebar from './sidebar';
import PatternList from './patterns-list';
import { usePatternsCategories } from '../block-patterns-tab';
import { store as blockEditorStore } from '../../../store';

function PatternsExplorer( { initialCategory, patternCategories } ) {
const [ filterValue, setFilterValue ] = useState( '' );
function PatternsExplorer( { initialCategory, rootClientId } ) {
const [ searchValue, setSearchValue ] = useState( '' );
const [ patternSourceFilter, setPatternSourceFilter ] = useState( 'all' );
const patternSyncFilter = useSelect( ( select ) => {
const { getSettings } = select( blockEditorStore );
const settings = getSettings();
return settings.patternsSyncFilter || 'all';
}, [] );
const [ selectedCategory, setSelectedCategory ] = useState(
initialCategory?.name
);

const previousSyncFilter = usePrevious( patternSyncFilter );

// If the sync filter changes, we need to select the "All" category to avoid
// showing a confusing no results screen.
useEffect( () => {
if ( patternSyncFilter && patternSyncFilter !== previousSyncFilter ) {
setSelectedCategory( initialCategory?.name );
}
}, [
patternSyncFilter,
previousSyncFilter,
patternSourceFilter,
initialCategory?.name,
] );

const patternCategories = usePatternsCategories(
rootClientId,
patternSourceFilter,
patternSyncFilter
);

return (
<div className="block-editor-block-patterns-explorer">
<PatternExplorerSidebar
selectedCategory={ selectedCategory }
patternCategories={ patternCategories }
onClickCategory={ setSelectedCategory }
filterValue={ filterValue }
setFilterValue={ setFilterValue }
searchValue={ searchValue }
setSearchValue={ setSearchValue }
patternSourceFilter={ patternSourceFilter }
setPatternSourceFilter={ setPatternSourceFilter }
/>
<PatternList
filterValue={ filterValue }
searchValue={ searchValue }
selectedCategory={ selectedCategory }
patternCategories={ patternCategories }
patternSourceFilter={ patternSourceFilter }
patternSyncFilter={ patternSyncFilter }
/>
</div>
);
Expand Down
Loading
Loading