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

DataViews: Use button for patterns, pages and templates preview field #58071

Merged
merged 10 commits into from
Jan 23, 2024
2 changes: 1 addition & 1 deletion packages/dataviews/src/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -285,9 +285,9 @@
width: 100%;
min-height: 200px;
aspect-ratio: 1/1;
overflow: hidden;
border-bottom: 1px solid $gray-200;
background-color: $gray-100;
border-radius: 3px 3px 0 0;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is the rounded corner value 3px in this PR? How about making the corners the same as the rounded corners of the card itself?

border-radius: $radius-block-ui * 2 $radius-block-ui * 2 0 0;

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it matches precisely then there's a small space where the background is visible between the card and the media wrapper / button. You have to zoom in to see it:

Screenshot 2024-01-23 at 10 57 43

I appreciate we could avoid the additional border-radius styles if we apply overflow: hidden to the card, but then the button focus style would be hidden.

If you have another idea how to tackle this please let me know, or feel free to push to the branch :)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for your detailed explanation! I can't think of any good ideas for now, so Iet's keep these styles 😅


img {
object-fit: cover;
Expand Down
69 changes: 39 additions & 30 deletions packages/edit-site/src/components/page-pages/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import { DataViews } from '@wordpress/dataviews';
* Internal dependencies
*/
import Page from '../page';
import Link from '../routes/link';
import { default as Link, useLink } from '../routes/link';
import {
DEFAULT_VIEWS,
DEFAULT_CONFIG_PER_VIEW_TYPE,
Expand All @@ -40,6 +40,7 @@ import {
import AddNewPageModal from '../add-new-page';
import Media from '../media';
import { unlock } from '../../lock-unlock';

const { useLocation, useHistory } = unlock( routerPrivateApis );

const EMPTY_ARRAY = [];
Expand Down Expand Up @@ -150,6 +151,42 @@ const STATUSES = [
];
const DEFAULT_STATUSES = 'draft,future,pending,private,publish'; // All but 'trash'.

function FeaturedImage( { item, viewType } ) {
const { onClick } = useLink( {
postId: item.id,
postType: item.type,
canvas: 'edit',
} );
const hasMedia = !! item.featured_media;
return (
<span
className={ {
'edit-site-page-pages__media-wrapper':
viewType === LAYOUT_TABLE,
} }
>
<button
className="page-pages-preview-field__button"
type="button"
onClick={ onClick }
aria-label={ item.title?.rendered || __( '(no title)' ) }
>
{ hasMedia && (
<Media
className="edit-site-page-pages__featured-image"
id={ item.featured_media }
size={
viewType === LAYOUT_GRID
? [ 'large', 'full', 'medium', 'thumbnail' ]
: [ 'thumbnail', 'medium', 'large', 'full' ]
}
/>
) }
</button>
</span>
);
}

export default function PagePages() {
const postType = 'page';
const [ view, setView ] = useView( postType );
Expand Down Expand Up @@ -243,35 +280,7 @@ export default function PagePages() {
header: __( 'Featured Image' ),
getValue: ( { item } ) => item.featured_media,
render: ( { item } ) => (
<span
className={
view.type === LAYOUT_TABLE
? 'edit-site-page-pages__media-wrapper'
: ''
}
>
{ !! item.featured_media ? (
<Media
className="edit-site-page-pages__featured-image"
id={ item.featured_media }
size={
view.type === LAYOUT_GRID
? [
'large',
'full',
'medium',
'thumbnail',
]
: [
'thumbnail',
'medium',
'large',
'full',
]
}
/>
) : null }
</span>
<FeaturedImage item={ item } viewType={ view.type } />
),
enableSorting: false,
},
Expand Down
19 changes: 19 additions & 0 deletions packages/edit-site/src/components/page-pages/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,22 @@
width: 100%;
}
}

.page-pages-preview-field__button {
box-shadow: none;
border: none;
padding: 0;
background-color: unset;
box-sizing: border-box;
cursor: pointer;
overflow: hidden;
height: 100%;
width: 100%;
border-radius: 3px 3px 0 0;

&:focus-visible {
box-shadow: 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color);
// Windows High Contrast mode will show this outline, but not the box-shadow.
outline: 2px solid transparent;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,24 @@ const SYNC_FILTERS = [
},
];

function Preview( { item, viewType } ) {
function PreviewWrapper( { item, onClick, ariaDescribedBy, children } ) {
if ( item.type === PATTERN_TYPES.theme ) {
return children;
}
return (
<button
className="page-patterns-preview-field__button"
type="button"
onClick={ onClick }
aria-label={ item.title }
aria-describedby={ ariaDescribedBy }
>
{ children }
</button>
);
}

function Preview( { item, categoryId, viewType } ) {
const descriptionId = useId();
const isUserPattern = item.type === PATTERN_TYPES.user;
const isNonUserPattern = item.type === PATTERN_TYPES.theme;
Expand All @@ -129,15 +146,37 @@ function Preview( { item, viewType } ) {
);
}
const [ backgroundColor ] = useGlobalStyle( 'color.background' );
const { onClick } = useLink( {
postType: item.type,
postId: isUserPattern ? item.id : item.name,
categoryId,
categoryType: isTemplatePart ? item.type : PATTERN_TYPES.theme,
} );

return (
<>
<div
className={ `page-patterns-preview-field is-viewtype-${ viewType }` }
style={ { backgroundColor } }
>
{ isEmpty && isTemplatePart && __( 'Empty template part' ) }
{ isEmpty && ! isTemplatePart && __( 'Empty pattern' ) }
{ ! isEmpty && <BlockPreview blocks={ item.blocks } /> }
<PreviewWrapper
item={ item }
onClick={ onClick }
ariaDescribedBy={
ariaDescriptions.length
? ariaDescriptions
.map(
( _, index ) =>
`${ descriptionId }-${ index }`
)
.join( ' ' )
: undefined
}
>
{ isEmpty && isTemplatePart && __( 'Empty template part' ) }
{ isEmpty && ! isTemplatePart && __( 'Empty pattern' ) }
{ ! isEmpty && <BlockPreview blocks={ item.blocks } /> }
</PreviewWrapper>
</div>
{ ariaDescriptions.map( ( ariaDescription, index ) => (
<div
Expand Down Expand Up @@ -245,7 +284,11 @@ export default function DataviewsPatterns() {
header: __( 'Preview' ),
id: 'preview',
render: ( { item } ) => (
<Preview item={ item } viewType={ view.type } />
<Preview
item={ item }
categoryId={ categoryId }
viewType={ view.type }
/>
),
enableSorting: false,
enableHiding: false,
Expand Down
26 changes: 25 additions & 1 deletion packages/edit-site/src/components/page-patterns/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -231,9 +231,33 @@
*/
.edit-site-page-patterns-dataviews {
.page-patterns-preview-field {
display: flex;
flex-direction: column;
height: 100%;
border-radius: 3px 3px 0 0;

&.is-viewtype-grid {
.block-editor-block-preview__container {
height: auto;
height: 100%;
border-radius: 3px 3px 0 0;
}
}

.page-patterns-preview-field__button {
box-shadow: none;
border: none;
padding: 0;
background-color: unset;
box-sizing: border-box;
cursor: pointer;
overflow: hidden;
height: 100%;
border-radius: 3px 3px 0 0;

&:focus-visible {
box-shadow: 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color);
// Windows High Contrast mode will show this outline, but not the box-shadow.
outline: 2px solid transparent;
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ import { privateApis as routerPrivateApis } from '@wordpress/router';
* Internal dependencies
*/
import Page from '../page';
import Link from '../routes/link';
import { default as Link, useLink } from '../routes/link';
import AddNewTemplate from '../add-new-template';
import { useAddedBy, AvatarImage } from '../list/added-by';
import {
Expand Down Expand Up @@ -132,15 +132,18 @@ function AuthorField( { item, viewType } ) {
);
}

function Preview( { content, viewType } ) {
function Preview( { item, viewType } ) {
const settings = usePatternSettings();
const [ backgroundColor = 'white' ] = useGlobalStyle( 'color.background' );
const blocks = useMemo( () => {
return parse( content );
}, [ content ] );
if ( ! blocks?.length ) {
return null;
}
return parse( item.content.raw );
}, [ item.content.raw ] );
const { onClick } = useLink( {
postId: item.id,
postType: item.type,
canvas: 'edit',
} );
const isEmpty = ! blocks?.length;
// Wrap everything in a block editor provider to ensure 'styles' that are needed
// for the previews are synced between the site editor store and the block editor store.
// Additionally we need to have the `__experimentalBlockPatterns` setting in order to
Expand All @@ -154,7 +157,18 @@ function Preview( { content, viewType } ) {
className={ `page-templates-preview-field is-viewtype-${ viewType }` }
style={ { backgroundColor } }
>
<BlockPreview blocks={ blocks } />
<button
className="page-templates-preview-field__button"
type="button"
onClick={ onClick }
aria-label={ item.title?.rendered || item.title }
>
{ isEmpty &&
( item.type === TEMPLATE_POST_TYPE
? __( 'Empty template' )
: __( 'Empty template part' ) ) }
{ ! isEmpty && <BlockPreview blocks={ blocks } /> }
</button>
</div>
</ExperimentalBlockEditorProvider>
);
Expand Down Expand Up @@ -210,12 +224,7 @@ export default function PageTemplatesTemplateParts( { postType } ) {
header: __( 'Preview' ),
id: 'preview',
render: ( { item } ) => {
return (
<Preview
content={ item.content.raw }
viewType={ view.type }
/>
);
return <Preview item={ item } viewType={ view.type } />;
},
minWidth: 120,
maxWidth: 120,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,27 @@
.page-templates-preview-field {
display: flex;
flex-direction: column;
height: 100%;
border-radius: 3px 3px 0 0;

.page-templates-preview-field__button {
box-shadow: none;
border: none;
padding: 0;
background-color: unset;
box-sizing: border-box;
cursor: pointer;
overflow: hidden;
height: 100%;
border-radius: 3px;

&:focus-visible {
box-shadow: 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color);
// Windows High Contrast mode will show this outline, but not the box-shadow.
outline: 2px solid transparent;
}
}

&.is-viewtype-list {
.block-editor-block-preview__container {
height: 120px;
Expand All @@ -9,6 +32,10 @@
.block-editor-block-preview__container {
height: auto;
}

.page-templates-preview-field__button {
border-radius: 3px 3px 0 0;
}
}
}

Expand Down
Loading