Skip to content

Instantly share code, notes, and snippets.

@psorensen
Created February 29, 2024 13:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save psorensen/d5928ac79e7d9f4751e66482801ac5ba to your computer and use it in GitHub Desktop.
Save psorensen/d5928ac79e7d9f4751e66482801ac5ba to your computer and use it in GitHub Desktop.
Image placeholder component
const { MediaPlaceholder, InspectorControls } = wp.blockEditor;
const { Spinner, FocalPointPicker, PanelBody } = wp.components;
const { __ } = wp.i18n;
import { useMedia } from '../hooks/use-media';
/**
* Image Component with Placeholder
*
* @param {object} props Component Props
* @returns
*/
const Image = ( props ) => {
const {
id,
size = 'medium',
onSelect,
focalPoint = { x: 0.5, y: 0.5 },
onChangeFocalPoint,
...rest
} = props;
const hasImage = !!id;
const { media, isResolvingMedia } = useMedia( id );
const shouldDisplayFocalPointPicker =
'function' === typeof onChangeFocalPoint;
if ( ! hasImage ) {
return (
<MediaPlaceholder onSelect={onSelect} accept="image" multiple={false} />
);
}
if ( isResolvingMedia ) {
return <Spinner />;
}
const imageUrl =
media?.media_details?.sizes[size]?.source_url ?? media?.source_url;
const altText = media?.alt_text;
if ( shouldDisplayFocalPointPicker ) {
const focalPointStyle = {
objectFit: 'cover',
objectPosition: `${focalPoint.x * 100}% ${focalPoint.y * 100}%`,
};
rest.style = {
...rest.style,
...focalPointStyle,
};
}
return (
<>
{shouldDisplayFocalPointPicker && (
<InspectorControls>
<PanelBody title={__( 'Image Settings', 'starbucks' )}>
<FocalPointPicker
label={__( 'Focal Point Picker', 'starbucks' )}
url={imageUrl}
value={focalPoint}
onChange={onChangeFocalPoint}
/>
</PanelBody>
</InspectorControls>
)}
<img src={imageUrl} alt={altText} {...rest} />
</>
);
};
export { Image };
const { useSelect } = wp.data;
const { store: coreStore } = wp.coreData;
/**
* Use Media from WP Core
*
* @param {Number} id Media ID
* @returns {Object} Media Object
*/
export function useMedia( id ) {
return useSelect(
( select ) => {
const { getMedia, isResolving, hasFinishedResolution } = select( coreStore );
const mediaParameters = [ id, { context: 'view' } ];
return {
media: getMedia( ...mediaParameters ),
isResolvingMedia: isResolving( 'getMedia', mediaParameters ),
hasResolvedMedia: hasFinishedResolution( 'getMedia', mediaParameters ),
};
},
[ id ],
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment