Skip to content

Commit 842e7cd

Browse files
committed
Added Image and FocalPointImage components. Added example of how to build an Image Control with Focal Point Picker flow.
1 parent 4efdb0f commit 842e7cd

File tree

10 files changed

+190
-5
lines changed

10 files changed

+190
-5
lines changed

README.md

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,40 @@ To include the editor styles, add this to the top of your block's `_editor.scss`
1010

1111
## Components
1212

13+
### FocalPointImage
14+
15+
Purely presentational component, which helps work with the `FocalPointPicker` from `@wordpress/components`.
16+
17+
Renders a standard `<img />` element from data received from the MediaUpload flow. See `<Image>` below for all available props.
18+
19+
```javascript
20+
<FocalPointImage
21+
url="https://..."
22+
focalPoint={{
23+
x: 0.5,
24+
y: 0.5,
25+
}}
26+
/>
27+
```
28+
29+
### Image
30+
31+
Simple presentational component, which renders a standard `<img />` element from data format which is received from the MediaUpload flow.
32+
33+
For example instead of `src` it uses an `url` prop etc.
34+
35+
```javascript
36+
<Image
37+
id={myImageId}
38+
url="https://..."
39+
alt="My alt text"
40+
width={1600}
41+
height={900}
42+
title="My title text"
43+
loading="lazy"
44+
/>
45+
```
46+
1347
### ImageControl
1448

1549
Simple image upload and replacement flow for managing media.
@@ -265,8 +299,96 @@ export default function Edit({ attributes, setAttributes }) {
265299
}
266300
```
267301

302+
### Image Control with Focal Point Picker
303+
304+
This flow describes how to setup image media management with a focal point picker:
305+
306+
![Image Control with Focal Point Picker example](assets/ImageControlWithFocalPointPicker-screenshot-01.png)
307+
308+
First, you need two attributes for your block's `block.json`:
309+
310+
```json
311+
{
312+
"attributes": {
313+
"myImage": {
314+
"type": "object"
315+
},
316+
"myFocalPoint": {
317+
"type": "object"
318+
}
319+
}
320+
}
321+
```
322+
323+
In your block's `edit.js`, use `ImageControl` from this toolkit and `FocalPointPicker` from `@wordpress/components`.
324+
325+
Note how we disable the preview of ImageControl with `showPreview` set to `false`. This allows us to replace it with the focal point picker control after a media item has been selected.
326+
327+
Whenever the media item is removed, we also reset the focal point.
328+
329+
Then use `FocalPointImage` from this toolkit to render the positioned image result.
330+
331+
```javascript
332+
import {
333+
ImageControl,
334+
FocalPointImage,
335+
utils,
336+
} from "@evermade/wp-block-toolkit";
337+
338+
import { FocalPointPicker } from "@wordpress/components";
339+
import { InspectorControls } from "@wordpress/block-editor";
340+
import { Fragment } from "@wordpress/element";
341+
342+
export default function Edit({ attributes, setAttributes }) {
343+
const { myImage, myFocalPoint } = attributes;
344+
345+
return (
346+
<Fragment>
347+
<InspectorControls>
348+
{myImage && (
349+
<FocalPointPicker
350+
url={myImage?.url}
351+
value={myFocalPoint}
352+
onChange={(newFocalPoint) =>
353+
setAttributes({
354+
myFocalPoint: newFocalPoint,
355+
})
356+
}
357+
/>
358+
)}
359+
360+
<ImageControl
361+
id={myImage?.id}
362+
showPreview={false}
363+
onSelect={(image) =>
364+
setAttributes({
365+
myImage: utils.pickImageProps(image),
366+
})
367+
}
368+
onRemove={() =>
369+
setAttributes({
370+
myImage: undefined,
371+
myFocalPoint: undefined,
372+
})
373+
}
374+
/>
375+
</InspectorControls>
376+
377+
<div className="my-block">
378+
{myImage && <FocalPointImage {...myImage} focalPoint={myFocalPoint} />}
379+
</div>
380+
</Fragment>
381+
);
382+
}
383+
```
384+
268385
## Changelog
269386
387+
### 7.1.0
388+
389+
- Fixed `ImageControl` export to default.
390+
- Added `Image` and `FocalPointImage` presentational components.
391+
270392
### 7.0.0
271393
272394
- Updated npm dependencies
98.6 KB
Loading

build/index.asset.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
<?php return array('dependencies' => array('react', 'react-dom', 'react-jsx-runtime', 'wp-block-editor', 'wp-components', 'wp-data', 'wp-element', 'wp-i18n', 'wp-primitives'), 'version' => 'e0aa4d99057053f9e5e4');
1+
<?php return array('dependencies' => array('react', 'react-dom', 'react-jsx-runtime', 'wp-block-editor', 'wp-components', 'wp-data', 'wp-element', 'wp-i18n', 'wp-primitives'), 'version' => '9cb812ccf9d5225f2fbd');

build/index.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

index.d.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,27 @@ type BlockNames = string[];
55
/**
66
* Components
77
*/
8+
type ImageProps = {
9+
id: number;
10+
url: string;
11+
alt: string;
12+
width: number;
13+
height: number;
14+
title: string;
15+
loading: "lazy" | "eager";
16+
};
17+
18+
export const FocalPointImage: React.FC<
19+
ImageProps & {
20+
focalPoint: {
21+
x: number;
22+
y: number;
23+
};
24+
}
25+
>;
26+
27+
export const Image: React.FC<ImageProps>;
28+
829
export const ImageControl: React.FC<{
930
id: number;
1031
fallback: string;

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@evermade/wp-block-toolkit",
3-
"version": "7.0.0",
3+
"version": "7.1.0",
44
"description": "Toolkit for developing WordPress Gutenberg blocks.",
55
"main": "build/index.js",
66
"repository": {

src/components/FocalPointImage.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import Image from "./Image";
2+
3+
const FocalPointImage = ({ focalPoint = { x: 0.5, y: 0.5 }, ...props }) => {
4+
const style = {
5+
objectPosition: `${focalPoint.x * 100}% ${focalPoint.y * 100}%`,
6+
};
7+
8+
return <Image {...props} style={style} />;
9+
};
10+
11+
export default FocalPointImage;

src/components/Image.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
export const Image = ({
2+
id,
3+
url,
4+
alt,
5+
width,
6+
height,
7+
title,
8+
loading = "lazy",
9+
...rest
10+
}) => {
11+
return (
12+
<img
13+
src={url}
14+
alt={alt}
15+
width={width}
16+
height={height}
17+
title={title}
18+
loading={loading}
19+
className={`wp-image-${id}`}
20+
{...rest}
21+
/>
22+
);
23+
};
24+
25+
export default Image;

src/components/ImageControl.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import { useSelect } from "@wordpress/data";
1212
import { MediaUpload, MediaUploadCheck } from "@wordpress/block-editor";
1313
import { Fragment } from "@wordpress/element";
1414

15-
export const ImageControl = ({
15+
const ImageControl = ({
1616
id,
1717
fallback = __(
1818
"You don't have permission to upload media.",
@@ -97,3 +97,5 @@ export const ImageControl = ({
9797
</div>
9898
);
9999
};
100+
101+
export default ImageControl;

src/index.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@ import "./editor.scss";
66
/**
77
* Components
88
*/
9-
import { ImageControl } from "./components/ImageControl";
9+
import FocalPointImage from "./components/FocalPointImage";
10+
import Image from "./components/Image";
11+
import ImageControl from "./components/ImageControl";
1012
import InlineNotice from "./components/InlineNotice";
1113
import PostControl from "./components/PostControl";
1214
import RequireBlocks from "./components/RequireBlocks";
@@ -29,6 +31,8 @@ import { usePostSearch } from "./hooks/use-post-search";
2931
import * as utils from "./utils";
3032

3133
export {
34+
FocalPointImage,
35+
Image,
3236
ImageControl,
3337
InlineNotice,
3438
PostControl,

0 commit comments

Comments
 (0)