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 categories to user patterns, and allow filtering by these in site and post editor #53835

Merged
merged 20 commits into from Sep 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
2555e94
Add category selection option to create pattern modal
glendaviesnz Sep 14, 2023
35b255c
Fix linting error
glendaviesnz Aug 21, 2023
25df1b3
Limit width of categories field
glendaviesnz Aug 21, 2023
9b62adf
Tidy up category selector file
glendaviesnz Aug 21, 2023
61d04ea
Add user pattern categories to the core data store
glendaviesnz Aug 24, 2023
53a756f
Make accumulator terms a bit more explicit
glendaviesnz Aug 24, 2023
869d416
Fix category name mapping
glendaviesnz Aug 24, 2023
cec0414
Invalidate category resolver when new category added
glendaviesnz Aug 25, 2023
8a08e2b
Fix typos
glendaviesnz Aug 29, 2023
5109013
Components: FormTokenField - add prop to allow saving of tokens onBlur
glendaviesnz Sep 14, 2023
6fd3cee
Revert "Components: FormTokenField - add prop to allow saving of toke…
glendaviesnz Sep 14, 2023
982c246
Patterns: Add user categories to site editor sidebar navigation screen
glendaviesnz Sep 15, 2023
6708eda
Patterns: Add user pattern categories to post editor inserter pattern…
glendaviesnz Sep 14, 2023
b3ec223
Remove the USER_PATTERN_CATEGORY
glendaviesnz Sep 14, 2023
6a50714
Fix input height
glendaviesnz Sep 14, 2023
360d0f2
Fix bug with editor crashing on search of patterns
glendaviesnz Sep 14, 2023
5d24d16
Add category to the pattern details panel
glendaviesnz Sep 15, 2023
9d24678
Fix uncategorized logic
glendaviesnz Sep 15, 2023
8669bee
Fix current navigation regression
glendaviesnz Sep 15, 2023
85f4c5e
Patterns: Update pattern inserter to show all categories regardless o…
glendaviesnz Sep 15, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
12 changes: 12 additions & 0 deletions docs/reference-guides/data/data-core.md
Expand Up @@ -403,6 +403,18 @@ _Returns_

- `Optional< any >`: The edit.

### getUserPatternCategories

Retrieve the registered user pattern categories.

_Parameters_

- _state_ `State`: Data state.

_Returns_

- `UserPatternCategories`: User patterns category array and map keyed by id.

### getUserQueryResults

Returns all the users returned by a query ID.
Expand Down
25 changes: 12 additions & 13 deletions lib/compat/wordpress-6.4/block-patterns.php
Expand Up @@ -16,20 +16,19 @@
*/
function gutenberg_register_taxonomy_patterns() {
$args = array(
array(
'public' => false,
'hierarchical' => false,
'labels' => array(
'name' => _x( 'Pattern Categories', 'taxonomy general name' ),
'singular_name' => _x( 'Pattern Category', 'taxonomy singular name' ),
),
'query_var' => false,
'rewrite' => false,
'show_ui' => false,
'_builtin' => true,
'show_in_nav_menus' => false,
'show_in_rest' => true,
'public' => true,
'hierarchical' => false,
'labels' => array(
'name' => _x( 'Pattern Categories', 'taxonomy general name' ),
'singular_name' => _x( 'Pattern Category', 'taxonomy singular name' ),
),
'query_var' => false,
'rewrite' => false,
'show_ui' => true,
'_builtin' => true,
'show_in_nav_menus' => false,
'show_in_rest' => true,
'show_admin_column' => true,
);
register_taxonomy( 'wp_pattern_category', array( 'wp_block' ), $args );
}
Expand Down
2 changes: 2 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

@@ -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
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);
}
}
}
@@ -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>
);
}
@@ -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);
}
}
}
}
3 changes: 3 additions & 0 deletions packages/block-editor/src/components/iframe/index.js
Expand Up @@ -68,6 +68,9 @@ function bubbleEvent( event, Constructor, frame ) {
function useBubbleEvents( iframeDocument ) {
return useRefEffect( ( body ) => {
const { defaultView } = iframeDocument;
if ( ! defaultView ) {
return;
}
const { frameElement } = defaultView;
const eventTypes = [ 'dragover', 'mousemove' ];
const handlers = {};
Expand Down
Expand Up @@ -10,25 +10,37 @@ import { __ } from '@wordpress/i18n';
*/
import PatternExplorerSidebar from './sidebar';
import PatternList from './patterns-list';
import { usePatternsCategories } from '../block-patterns-tab';

function PatternsExplorer( { initialCategory, rootClientId } ) {
const [ searchValue, setSearchValue ] = useState( '' );
const [ patternSourceFilter, setPatternSourceFilter ] = useState( 'all' );

function PatternsExplorer( { initialCategory, patternCategories } ) {
const [ filterValue, setFilterValue ] = useState( '' );
const [ selectedCategory, setSelectedCategory ] = useState(
initialCategory?.name
);

const patternCategories = usePatternsCategories(
rootClientId,
patternSourceFilter
);

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 }
/>
</div>
);
Expand Down