@secretstache/wordpress-gutenberg 0.5.3 → 0.5.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/index.js +3 -3
- package/build/index.js.map +1 -1
- package/build/styles.css +2 -0
- package/package.json +1 -1
- package/src/components/MediaControl.js +91 -58
- package/src/components/MediaWithFocalPointControl.js +78 -0
- package/src/components/index.js +7 -6
- package/src/styles/_link-control.scss +4 -0
- package/src/utils/helpers.js +19 -0
package/build/styles.css
CHANGED
@@ -153,6 +153,8 @@
|
|
153
153
|
.editor-sidebar .block-editor-link-control {
|
154
154
|
min-width: 100%;
|
155
155
|
width: 100%; }
|
156
|
+
.editor-sidebar .block-editor-link-control .block-editor-url-input {
|
157
|
+
min-width: 100%; }
|
156
158
|
.editor-sidebar .block-editor-link-control .block-editor-url-input__input {
|
157
159
|
width: 100%; }
|
158
160
|
.editor-sidebar .block-editor-link-control .components-base-control {
|
package/package.json
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
import { Button, Icon as WPIcon } from '@wordpress/components';
|
1
|
+
import { BaseControl, Button, FocalPointPicker, Icon as WPIcon } from '@wordpress/components';
|
2
2
|
import { MediaUpload, MediaUploadCheck } from '@wordpress/block-editor';
|
3
3
|
import { page as pageIcon } from '@wordpress/icons';
|
4
4
|
|
@@ -110,81 +110,114 @@ export const AnimationRenderer = ({
|
|
110
110
|
};
|
111
111
|
|
112
112
|
export const MediaControl = ({
|
113
|
+
type = MEDIA_TYPE.IMAGE,
|
114
|
+
label,
|
115
|
+
|
113
116
|
mediaId,
|
114
117
|
mediaUrl,
|
115
118
|
mediaFileName = '',
|
119
|
+
|
116
120
|
onSelect,
|
117
121
|
onRemove,
|
118
|
-
|
122
|
+
|
119
123
|
selectButtonLabel,
|
120
124
|
removeButtonLabel,
|
125
|
+
|
126
|
+
hasFocalPoint = true,
|
127
|
+
focalPointLabel = 'Focal Point',
|
128
|
+
focalPoint = { x: 0.5, y: 0.5 },
|
129
|
+
onFocalPointChange,
|
130
|
+
|
121
131
|
...other
|
122
132
|
}) => {
|
123
133
|
if (type === MEDIA_TYPE.IMAGE) {
|
124
134
|
return (
|
125
|
-
|
126
|
-
<
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
135
|
+
<>
|
136
|
+
<BaseControl label={label || 'Image'}>
|
137
|
+
<MediaUploadCheck>
|
138
|
+
<MediaUpload
|
139
|
+
onSelect={onSelect}
|
140
|
+
allowedTypes={['image', 'image/svg+xml']}
|
141
|
+
accept="image/*"
|
142
|
+
value={mediaId}
|
143
|
+
render={({ open }) => (
|
144
|
+
<ImageRenderer
|
145
|
+
imageId={mediaId}
|
146
|
+
imageUrl={mediaUrl}
|
147
|
+
onImageClick={open}
|
148
|
+
onSelectClick={open}
|
149
|
+
onRemoveClick={onRemove}
|
150
|
+
selectButtonLabel={selectButtonLabel || 'Select Image'}
|
151
|
+
removeButtonLabel={removeButtonLabel || 'Remove Image'}
|
152
|
+
/>
|
153
|
+
)}
|
154
|
+
{...other}
|
140
155
|
/>
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
156
|
+
</MediaUploadCheck>
|
157
|
+
</BaseControl>
|
158
|
+
|
159
|
+
{
|
160
|
+
hasFocalPoint && mediaId && mediaUrl && (
|
161
|
+
<BaseControl label={focalPointLabel}>
|
162
|
+
<FocalPointPicker
|
163
|
+
__nextHasNoMarginBottom
|
164
|
+
url={mediaUrl}
|
165
|
+
value={focalPoint}
|
166
|
+
onDragStart={onFocalPointChange}
|
167
|
+
onDrag={onFocalPointChange}
|
168
|
+
onChange={onFocalPointChange}
|
169
|
+
/>
|
170
|
+
</BaseControl>
|
171
|
+
)
|
172
|
+
}
|
173
|
+
</>
|
145
174
|
);
|
146
175
|
} else if (type === MEDIA_TYPE.VIDEO) {
|
147
176
|
return (
|
148
|
-
<
|
149
|
-
<
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
177
|
+
<BaseControl label={label || 'Video'}>
|
178
|
+
<MediaUploadCheck>
|
179
|
+
<MediaUpload
|
180
|
+
onSelect={onSelect}
|
181
|
+
allowedTypes={['video']}
|
182
|
+
value={mediaId}
|
183
|
+
render={({ open }) => (
|
184
|
+
<VideoRenderer
|
185
|
+
videoId={mediaId}
|
186
|
+
videoUrl={mediaUrl}
|
187
|
+
onSelectClick={open}
|
188
|
+
onRemoveClick={onRemove}
|
189
|
+
selectButtonLabel={selectButtonLabel || 'Select Video'}
|
190
|
+
removeButtonLabel={removeButtonLabel || 'Remove Video'}
|
191
|
+
/>
|
192
|
+
)}
|
193
|
+
{...other}
|
194
|
+
/>
|
195
|
+
</MediaUploadCheck>
|
196
|
+
</BaseControl>
|
166
197
|
);
|
167
198
|
} else if (type === MEDIA_TYPE.ANIMATION) {
|
168
199
|
return (
|
169
|
-
<
|
170
|
-
<
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
200
|
+
<BaseControl label={label || 'Animation'}>
|
201
|
+
<MediaUploadCheck>
|
202
|
+
<MediaUpload
|
203
|
+
onSelect={onSelect}
|
204
|
+
allowedTypes={['application/json', 'text/plain', 'application/lottie']}
|
205
|
+
value={mediaId}
|
206
|
+
render={({ open }) => (
|
207
|
+
<AnimationRenderer
|
208
|
+
animationFileId={mediaId}
|
209
|
+
animationFileUrl={mediaUrl}
|
210
|
+
animationFileName={mediaFileName}
|
211
|
+
onSelectClick={open}
|
212
|
+
onRemoveClick={onRemove}
|
213
|
+
selectButtonLabel={selectButtonLabel || 'Select Animation'}
|
214
|
+
removeButtonLabel={removeButtonLabel || 'Remove Animation'}
|
215
|
+
/>
|
216
|
+
)}
|
217
|
+
{...other}
|
218
|
+
/>
|
219
|
+
</MediaUploadCheck>
|
220
|
+
</BaseControl>
|
188
221
|
);
|
189
222
|
} else {
|
190
223
|
throw new Error('Unrecognized media type.');
|
@@ -0,0 +1,78 @@
|
|
1
|
+
import { BaseControl, FocalPointPicker } from '@wordpress/components';
|
2
|
+
import { useCallback, memo } from '@wordpress/element';
|
3
|
+
|
4
|
+
import { MediaControl } from './MediaControl.js';
|
5
|
+
import { MEDIA_TYPE } from '../utils/index.js';
|
6
|
+
|
7
|
+
/**
|
8
|
+
* Media control with focal point functionality
|
9
|
+
*
|
10
|
+
* @param {Object} props - Component props
|
11
|
+
* @returns {JSX.Element} Component JSX
|
12
|
+
*/
|
13
|
+
export const MediaWithFocalPointControl = memo(({
|
14
|
+
attributes,
|
15
|
+
setAttributes,
|
16
|
+
mediaAttributeName = 'media',
|
17
|
+
focalPointAttributeName = 'focalPoint',
|
18
|
+
mediaLabel = 'Image',
|
19
|
+
focalPointLabel = 'Focal Point',
|
20
|
+
mediaControlProps = {},
|
21
|
+
}) => {
|
22
|
+
const media = attributes[mediaAttributeName];
|
23
|
+
const focalPoint = attributes[focalPointAttributeName] || { x: 0.5, y: 0.5 };
|
24
|
+
|
25
|
+
const onFocalPointChange = useCallback((newFocalPoint) => {
|
26
|
+
setAttributes({ [focalPointAttributeName]: newFocalPoint });
|
27
|
+
}, [ focalPointAttributeName ]);
|
28
|
+
|
29
|
+
const onMediaSelect = useCallback((newMedia) => {
|
30
|
+
setAttributes({
|
31
|
+
[mediaAttributeName]: {
|
32
|
+
id: newMedia.id,
|
33
|
+
url: newMedia.url,
|
34
|
+
alt: newMedia.alt || '',
|
35
|
+
},
|
36
|
+
|
37
|
+
[focalPointAttributeName]: { x: 0.5, y: 0.5 }
|
38
|
+
});
|
39
|
+
}, [ mediaAttributeName ]);
|
40
|
+
|
41
|
+
const onMediaRemove = useCallback(() => {
|
42
|
+
setAttributes({
|
43
|
+
[mediaAttributeName]: {
|
44
|
+
id: null,
|
45
|
+
url: null,
|
46
|
+
alt: null,
|
47
|
+
}
|
48
|
+
});
|
49
|
+
}, [ mediaAttributeName ]);
|
50
|
+
|
51
|
+
return (
|
52
|
+
<>
|
53
|
+
<BaseControl label={mediaLabel}>
|
54
|
+
<MediaControl
|
55
|
+
type={MEDIA_TYPE.IMAGE}
|
56
|
+
mediaId={media?.id}
|
57
|
+
mediaUrl={media?.url}
|
58
|
+
onSelect={onMediaSelect}
|
59
|
+
onRemove={onMediaRemove}
|
60
|
+
{...mediaControlProps}
|
61
|
+
/>
|
62
|
+
</BaseControl>
|
63
|
+
|
64
|
+
{media?.url && (
|
65
|
+
<BaseControl label={focalPointLabel}>
|
66
|
+
<FocalPointPicker
|
67
|
+
__nextHasNoMarginBottom
|
68
|
+
url={media.url}
|
69
|
+
value={focalPoint}
|
70
|
+
onDragStart={onFocalPointChange}
|
71
|
+
onDrag={onFocalPointChange}
|
72
|
+
onChange={onFocalPointChange}
|
73
|
+
/>
|
74
|
+
</BaseControl>
|
75
|
+
)}
|
76
|
+
</>
|
77
|
+
);
|
78
|
+
});
|
package/src/components/index.js
CHANGED
@@ -7,9 +7,10 @@ export { SortableSelect, SortableSelectAsync } from './SortableSelect';
|
|
7
7
|
export { DataQueryControls } from './DataQueryControls.js';
|
8
8
|
export { SpacingControl } from './SpacingControl.js';
|
9
9
|
export { ResponsiveSpacingControl } from './ResponsiveSpacingControl.js';
|
10
|
-
export { ResourcesWrapper } from './ResourcesWrapper.js'
|
11
|
-
export { DividersControl } from './DividersControl.js'
|
12
|
-
export { MediaTypeControl } from './MediaTypeControl.js'
|
13
|
-
export { InsertBlockToolbar } from './InsertBlockToolbar.js'
|
14
|
-
export { PreviewControl } from './PreviewControl.js'
|
15
|
-
export { EmptyBlockAppender } from './EmptyBlockAppender.js'
|
10
|
+
export { ResourcesWrapper } from './ResourcesWrapper.js';
|
11
|
+
export { DividersControl } from './DividersControl.js';
|
12
|
+
export { MediaTypeControl } from './MediaTypeControl.js';
|
13
|
+
export { InsertBlockToolbar } from './InsertBlockToolbar.js';
|
14
|
+
export { PreviewControl } from './PreviewControl.js';
|
15
|
+
export { EmptyBlockAppender } from './EmptyBlockAppender.js';
|
16
|
+
export { MediaWithFocalPointControl } from './MediaWithFocalPointControl.js';
|
package/src/utils/helpers.js
CHANGED
@@ -254,3 +254,22 @@ export function updateBlockApiVersion(blockName, apiVersion = 3) {
|
|
254
254
|
});
|
255
255
|
}
|
256
256
|
}
|
257
|
+
|
258
|
+
/**
|
259
|
+
* Creates object-position style based on focal point coordinates
|
260
|
+
*
|
261
|
+
* @param {Object} focalPoint - Focal point coordinates { x, y }
|
262
|
+
* @returns {Object} Style object with objectPosition property
|
263
|
+
*/
|
264
|
+
export const getFocalPointStyle = (focalPoint) => {
|
265
|
+
if (!focalPoint) {
|
266
|
+
return { objectPosition: '50% 50%' };
|
267
|
+
}
|
268
|
+
|
269
|
+
// Handle edge case where x or y is 0
|
270
|
+
const x = (focalPoint.x !== undefined && focalPoint.x !== null) ? focalPoint.x * 100 : 50;
|
271
|
+
const y = (focalPoint.y !== undefined && focalPoint.y !== null) ? focalPoint.y * 100 : 50;
|
272
|
+
|
273
|
+
return { objectPosition: `${x}% ${y}%` };
|
274
|
+
};
|
275
|
+
|