-
Notifications
You must be signed in to change notification settings - Fork 4.2k
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: merge unsynced into inserter patterns tab and add paging and filtering #54007
Changes from 60 commits
fc921a7
8ca644b
9be8084
a098a7b
fda3f16
59a2e0c
f99c31d
516341c
d4705b7
39f33b2
4aa0623
81165ec
476ef8f
ce2aae9
f64f043
a8c0785
684e57e
2ad6587
a9c4ae7
f60beb8
71271f3
c62b4fd
de814a6
48dcd35
bb6cec5
cec2b9a
96b9459
26f486b
e2292a1
2f53ea2
bf74886
b8eadf5
2153343
1b4f30a
39e5f82
48c36e5
351204d
fc40fe7
5199163
6fbc699
4487351
616066d
f845d66
720d3cb
0ee4b81
8839f7a
5951dad
3a920f9
546026f
389285f
5fd5edc
2cb5cfc
f69a88f
57d54db
275e01e
f1f4edc
a37cdd3
da77818
8b94003
8458d29
c293dc7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
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 |
---|---|---|
|
@@ -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, | ||
] ); | ||
Comment on lines
+32
to
+43
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit: Could we rewrite this without the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yeh it would be nice to do that, but had a look and plumbing through the onCategorySelect method from modal.js file and using that causes the whole component tree to rerender and the modal gets closed. But would be great to refactor this component tree at some point to allow away for these changes to be handled in the relevant event handlers |
||
|
||
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> | ||
); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder where we should move the focus after navigating to a different page. Should we retain the focus on the prev/next button? Or should we move the focus to the first pattern to match the visual jump? If we decide to retain the focus then we probably want to change this to
aria-disabled
to prevent focus lost when pressing this button for instance. This can all be reviewed by an accessibility expert though, I'm just tossing out some questions 😅 .There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it would be good to look at this as a follow-up combined with the site editor pagination - ideally we should finalise the
pattern
we should use for this and see if we can have a generic pagination component that can be shared between site/post editor.