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

Try: Let Featured Image block inherit dimensions, look like a placeholder #36517

Merged
merged 4 commits into from
Nov 17, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 61 additions & 21 deletions packages/block-library/src/post-featured-image/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,34 +2,50 @@
* WordPress dependencies
*/
import { useEntityProp, store as coreStore } from '@wordpress/core-data';
import { useSelect } from '@wordpress/data';
import { useSelect, useDispatch } from '@wordpress/data';
import {
Icon,
ToggleControl,
PanelBody,
Placeholder,
withNotices,
Button,
} from '@wordpress/components';
import {
InspectorControls,
BlockControls,
MediaPlaceholder,
MediaReplaceFlow,
BlockIcon,
useBlockProps,
} from '@wordpress/block-editor';
import { __, sprintf } from '@wordpress/i18n';
import { postFeaturedImage } from '@wordpress/icons';
import { upload } from '@wordpress/icons';
import { SVG, Path } from '@wordpress/primitives';
import { store as noticesStore } from '@wordpress/notices';

/**
* Internal dependencies
*/
import DimensionControls from './dimension-controls';

const placeholderIllustration = (
<SVG
className="components-placeholder__illustration"
fill="none"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 60 60"
preserveAspectRatio="xMidYMid slice" // @todo: "slice" matches the "cover" behavior, "meet" could be used for "container" and "fill" values.
>
<Path
vectorEffect="non-scaling-stroke"
d="m61 32.622-13.555-9.137-15.888 9.859a5 5 0 0 1-5.386-.073l-9.095-5.989L1 37.5"
/>
</SVG>
);

const ALLOWED_MEDIA_TYPES = [ 'image' ];
const placeholderChip = (
<div className="post-featured-image_placeholder">
<Icon icon={ postFeaturedImage } />
<p> { __( 'Featured Image' ) }</p>
<div className="wp-block-post-featured-image__placeholder">
{ placeholderIllustration }
</div>
);

Expand All @@ -38,7 +54,6 @@ function PostFeaturedImageDisplay( {
setAttributes,
context: { postId, postType, queryId },
noticeUI,
noticeOperations,
} ) {
const isDescendentOfQueryLoop = !! queryId;
const { isLink, height, width, scale } = attributes;
Expand All @@ -48,42 +63,67 @@ function PostFeaturedImageDisplay( {
'featured_media',
postId
);

const media = useSelect(
( select ) =>
featuredImage &&
select( coreStore ).getMedia( featuredImage, { context: 'view' } ),
[ featuredImage ]
);

const blockProps = useBlockProps( {
style: { width },
style: { width, height },
} );

const placeholder = ( content ) => {
return (
<Placeholder className="block-editor-media-placeholder">
{ placeholderIllustration }
{ content }
</Placeholder>
);
};

const onSelectImage = ( value ) => {
if ( value?.id ) {
setFeaturedImage( value.id );
}
};
function onUploadError( message ) {
noticeOperations.removeAllNotices();
noticeOperations.createErrorNotice( message );
}

const { createErrorNotice } = useDispatch( noticesStore );
const onUploadError = ( message ) => {
createErrorNotice( message[ 2 ], { type: 'snackbar' } );
};

let image;
if ( ! featuredImage && isDescendentOfQueryLoop ) {
return <div { ...blockProps }>{ placeholderChip }</div>;
}

const label = __( 'Add a featured image' );

if ( ! featuredImage ) {
image = (
<MediaPlaceholder
icon={ <BlockIcon icon={ postFeaturedImage } /> }
onSelect={ onSelectImage }
notices={ noticeUI }
onError={ onUploadError }
accept="image/*"
allowedTypes={ ALLOWED_MEDIA_TYPES }
labels={ {
title: __( 'Featured image' ),
instructions: __(
'Upload a media file or pick one from your media library.'
),
onError={ onUploadError }
placeholder={ placeholder }
notices={ noticeUI }
mediaLibraryButton={ ( { open } ) => {
return (
<Button
icon={ upload }
variant="primary"
label={ label }
showTooltip
tooltipPosition="top center"
onClick={ () => {
open();
} }
/>
);
} }
/>
);
Expand Down
144 changes: 124 additions & 20 deletions packages/block-library/src/post-featured-image/editor.scss
Original file line number Diff line number Diff line change
@@ -1,33 +1,137 @@
div[data-type="core/post-featured-image"] {
img {
max-width: 100%;
height: auto;
display: block;
// Give the featured image placeholder the appearance of a literal image placeholder.
// @todo: this CSS is similar to that of the Site Logo. That makes it an opportunity
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Most of this code is copied verbatim from #35397, and suggests there is an opportunity to create a new component, such as InheritingPlaceholder (it'd need a better name), which comes with less content inside, usually just a single upload/media library button, minimal markup, and intentionally lets theme styles bleed in and affect it.

It doesn't necessarily have to happen as part of this PR, but it seems worth tracking if this PR goes any further.

// to create a new component for placeholders meant to inherit some theme styles.
.wp-block-post-featured-image.wp-block-post-featured-image {
// Inherit border radius from style variations.
.components-placeholder,
.components-resizable-box__container {
border-radius: inherit;
}
}

.editor-styles-wrapper {
.post-featured-image_placeholder {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

These styles were actually dead, and didn't target anything.

display: flex;
flex-direction: row;
// Style the placeholder.
.wp-block-post-featured-image__placeholder,
.components-placeholder {
justify-content: center;
align-items: center;
border-radius: $radius-block-ui;
background-color: $white;
box-shadow: inset 0 0 0 $border-width $gray-900;
padding: $grid-unit-15;
svg {
margin-right: $grid-unit-15;
box-shadow: none;
padding: 0;

// Hide the upload button, as it's also available in the media library.
.components-form-file-upload {
display: none;
}

// Position the spinner.
.components-placeholder__preview {
position: absolute;
top: $grid-unit-05;
right: $grid-unit-05;
bottom: $grid-unit-05;
left: $grid-unit-05;
background: rgba($white, 0.8);
display: flex;
align-items: center;
justify-content: center;
}

// Draw the dashed outline.
// By setting the dashed border to currentColor, we ensure it's visible
// against any background color.
color: currentColor;
background: transparent;
&::before {
content: "";
display: block;
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
border: $border-width dashed currentColor;
opacity: 0.3;
pointer-events: none;

// Inherit border radius from style variations.
border-radius: inherit;
}

// Style the upload button.
.components-placeholder__fieldset {
width: auto;
}

.components-button.components-button {
color: inherit;
padding: 0;
display: flex;
justify-content: center;
align-items: center;
width: $grid-unit-60;
height: $grid-unit-60;
border-radius: 50%;
position: relative;
visibility: hidden;

// Animation.
background: transparent;
transition: all 0.1s linear;
@include reduce-motion("transition");
}
p {
font-family: $default-font;
font-size: $default-font-size;
margin: 0;

.components-button.components-button > svg {
color: $white;
}

// Style the placeholder illustration.
.components-placeholder__illustration {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
width: 100%;
height: 100%;
stroke: currentColor;
stroke-dasharray: 3;
opacity: 0.3;
}

// Show default placeholder height when not resized.
min-height: 200px;
}

// Provide a minimum size for the placeholder when resized.
// Note, this should be as small as we can afford it, and exists only
// to ensure there's room for the upload button.
&[style*="height"] .components-placeholder {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Using this style we can override the default placeholder min-height with an explicit height as soon as one is applied to the container.

min-height: $grid-unit-60;
min-width: $grid-unit-60;
height: 100%;
width: 100%;
}

// Show upload button on block selection.
&.is-selected .components-button.components-button {
background: var(--wp-admin-theme-color);
border-color: var(--wp-admin-theme-color);
border-style: solid;
color: $white;
opacity: 1;
visibility: visible;
}
}

div[data-type="core/post-featured-image"] {
img {
max-width: 100%;
height: auto;
display: block;
}
}

.block-library-post-featured-image-dimension-controls {
margin-bottom: $grid-unit-10;

&.scale-control-is-visible {
margin-bottom: $grid-unit-20;
}
Expand Down
1 change: 1 addition & 0 deletions packages/block-library/src/site-logo/editor.scss
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
width: 120px;
}

// Style the placeholder.
.components-placeholder {
justify-content: center;
align-items: center;
Expand Down