base-js-sw 1.0.8 → 1.0.10

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.
@@ -91,6 +91,7 @@ export const ImagePicker = ({
91
91
  setAttributes={setAttributes}
92
92
  imageRef={imageRef}
93
93
  buttonText={buttonText}
94
+ crop={showCrop ? undefined : false}
94
95
  />
95
96
  )}
96
97
  </div>
@@ -144,9 +145,13 @@ export const ImagePickerPreview = ({
144
145
  imageElementWrapperClass = blockClass + '__image-wrapper';
145
146
  }
146
147
 
147
- let imagecrop = crop ? '1' : '0';
148
- if (imageObject.crop) {
149
- imagecrop = imageObject.crop.replace(/\s+/g, '-');
148
+ let imagecrop;
149
+ if (crop === false) {
150
+ imagecrop = '0';
151
+ } else if (typeof imageObject.crop === 'string' && imageObject.crop !== '') {
152
+ imagecrop = imageObject.crop === '0' ? '0' : imageObject.crop.replace(/\s+/g, '-');
153
+ } else {
154
+ imagecrop = '1';
150
155
  }
151
156
 
152
157
  let imageOptionsString = `images/width=${width},height=${height},crop=${imagecrop}`;
@@ -198,6 +203,7 @@ export const ImagePickerPreview = ({
198
203
  replaceText=''
199
204
  removeText=''
200
205
  imageId={imageObject.id}
206
+ crop={crop}
201
207
  />
202
208
  </MediaUploadCheck>
203
209
  ) : ( // No image
@@ -206,6 +212,7 @@ export const ImagePickerPreview = ({
206
212
  setAttributes={setAttributes}
207
213
  imageRef={imageRef}
208
214
  buttonText={buttonText}
215
+ crop={crop}
209
216
  />
210
217
  )}
211
218
  </div>
@@ -213,11 +220,11 @@ export const ImagePickerPreview = ({
213
220
  };
214
221
 
215
222
  // ============= Image Controls (appear over image within editor)
216
- export const EditImageButtons = ({ componentClass, setAttributes, replaceText, removeText, imageRef, imageId }) => {
223
+ export const EditImageButtons = ({ componentClass, setAttributes, replaceText, removeText, imageRef, imageId, crop }) => {
217
224
  return (
218
225
  <MediaUpload
219
226
  title={'Icon'}
220
- onSelect={(media) => updateImageAttr(setAttributes, media, imageRef)}
227
+ onSelect={(media) => updateImageAttr(setAttributes, media, imageRef, crop)}
221
228
  allowedTypes={['image']}
222
229
  value={imageId}
223
230
  render={({ open }) => (
@@ -236,7 +243,7 @@ export const EditImageButtons = ({ componentClass, setAttributes, replaceText, r
236
243
  className={componentClass + "__edit-button"}
237
244
  isDestructive
238
245
  onClick={(media) => {
239
- updateImageAttr(setAttributes, false, imageRef)
246
+ updateImageAttr(setAttributes, false, imageRef, crop)
240
247
  }}
241
248
  icon="remove"
242
249
  >
@@ -248,10 +255,7 @@ export const EditImageButtons = ({ componentClass, setAttributes, replaceText, r
248
255
  )
249
256
  }
250
257
 
251
- export const UploadImageButton = ({ componentClass, setAttributes, imageRef, buttonText }) => {
252
-
253
-
254
-
258
+ export const UploadImageButton = ({ componentClass, setAttributes, imageRef, buttonText, crop }) => {
255
259
  return (
256
260
  <MediaUploadCheck>
257
261
  <MediaUpload
@@ -287,20 +291,25 @@ const updateImageAttr = (
287
291
  setAttributes,
288
292
  media = false,
289
293
  imageRef,
294
+ crop = 'center center'
290
295
  ) => {
291
-
292
296
  imageRef ??= 'imageObject';
293
297
 
294
- let newImageUrl = media ? media.sizes.full.url : ''
298
+ let newImageUrl = media ? (media.sizes?.full?.url || media.url) : '';
295
299
 
300
+ let newImage = {
301
+ id: media ? media.id : 0,
302
+ url: newImageUrl,
303
+ alt: media ? media.alt : '',
304
+ };
305
+
306
+ if (crop === false) {
307
+ newImage.crop = '0';
308
+ } else {
309
+ newImage.crop = typeof crop === 'string' ? crop : 'center center';
310
+ }
296
311
 
297
312
  setAttributes({
298
- [imageRef]: {
299
- id: media.id,
300
- url: newImageUrl,
301
- alt: media.alt,
302
- crop: 'center center'
303
- },
313
+ [imageRef]: newImage,
304
314
  });
305
315
  };
306
-
@@ -1,7 +1,51 @@
1
1
  import { __experimentalLinkControl as LinkControl } from '@wordpress/blockEditor';
2
+ import { Icon, Tooltip } from '@wordpress/components';
3
+ import { external, update } from '@wordpress/icons';
2
4
  import { safeDecodeURI } from '@wordpress/url';
3
5
  import { useState, useEffect } from 'react';
4
- import './LinkPicker.scss';
6
+
7
+ const linkPickerStyles = `
8
+ .base-js-link-picker {
9
+ width: 100%;
10
+ max-width: 100%;
11
+ min-width: 0;
12
+ overflow-x: hidden;
13
+ }
14
+
15
+ .base-js-link-picker .block-editor-link-control {
16
+ width: 100%;
17
+ max-width: 100% !important;
18
+ min-width: 0 !important;
19
+ }
20
+
21
+ .base-js-link-picker .block-editor-link-control__search-input {
22
+ margin: 0 !important;
23
+ min-width: 0 !important;
24
+ }
25
+
26
+ .base-js-link-picker .components-input-control__container {
27
+ width: 90% !important;
28
+ max-width: 100%;
29
+ }
30
+
31
+ .base-js-link-picker__status {
32
+ display: flex;
33
+ align-items: center;
34
+ gap: 8px;
35
+ margin-top: 12px;
36
+ color: #757575;
37
+ cursor: help;
38
+ font-size: 13px;
39
+ line-height: 1.4;
40
+ }
41
+
42
+ .base-js-link-picker__status svg {
43
+ flex: 0 0 auto;
44
+ color: inherit;
45
+ fill: currentColor;
46
+ stroke: currentColor;
47
+ }
48
+ `;
5
49
 
6
50
  export const LinkPicker = ({ setAttributes, at, linkRef = 'link' }) => {
7
51
  // Get the current link object based on linkRef or fallback to an empty object
@@ -13,6 +57,12 @@ export const LinkPicker = ({ setAttributes, at, linkRef = 'link' }) => {
13
57
  const [localUrl, setLocalUrl] = useState(url || '');
14
58
  const [localId, setLocalId] = useState(id || '');
15
59
  const [localLinkTarget, setLocalLinkTarget] = useState(opensInNewTab);
60
+ const isInternalPost = Boolean(localId);
61
+ const hasLinkData = Boolean(localUrl || localId);
62
+ const statusLabel = isInternalPost ? 'Dynamic WordPress link' : 'External link';
63
+ const statusTooltip = isInternalPost
64
+ ? 'This is a dynamic link to a page within the website. If the page’s URL changes it will update automatically'
65
+ : 'This is a static link and does not auto-update.';
16
66
 
17
67
  // Effect to update attributes when the local state changes
18
68
  useEffect(() => {
@@ -26,40 +76,60 @@ export const LinkPicker = ({ setAttributes, at, linkRef = 'link' }) => {
26
76
  }, [localUrl, localId, localLinkTarget]); // Trigger whenever the URL, ID, or target changes
27
77
 
28
78
  const handleLinkChange = (updatedValue) => {
29
- console.log(updatedValue)
30
- const { url, opensInNewTab, id, kind } = updatedValue;
79
+ const { url, opensInNewTab, id } = updatedValue;
80
+ const nextUrl = url || '';
81
+ const isPostSelection = Boolean(id);
31
82
 
32
83
  // Update ID or URL depending on whether it's an internal post or an external link/anchor
33
- if (kind === 'post-type' && id) {
84
+ if (isPostSelection) {
34
85
  // Internal post, use ID
35
86
  setLocalId(id);
36
- setLocalUrl(url);
87
+ setLocalUrl(nextUrl);
37
88
  } else {
38
89
  // External or anchor link, use URL
39
- setLocalUrl(url);
90
+ setLocalUrl(nextUrl);
40
91
  setLocalId(''); // Clear the ID since we are using the URL
41
92
  }
42
93
 
43
94
  // Update the new tab option
44
- setLocalLinkTarget(opensInNewTab);
95
+ setLocalLinkTarget(Boolean(opensInNewTab));
45
96
  };
46
97
 
47
98
  return (
48
- <LinkControl
49
- value={{ url: localUrl, opensInNewTab: localLinkTarget, id: localId }}
50
- onChange={(updatedValue) => {
51
- handleLinkChange(updatedValue);
52
- }}
53
- onBlur={() => {
54
- // Save on blur to ensure the value is saved when clicking away
55
- setAttributes({
56
- [linkRef]: {
57
- url: localId ? '' : localUrl ? encodeURI(safeDecodeURI(localUrl)) : '',
58
- linkTarget: localLinkTarget ? '_blank' : undefined,
59
- id: localId ? localId : undefined,
60
- },
61
- });
62
- }}
63
- />
99
+ <div className="base-js-link-picker">
100
+ <style>{linkPickerStyles}</style>
101
+ <div className="base-js-link-picker__control">
102
+ <LinkControl
103
+ value={{ url: localUrl, opensInNewTab: localLinkTarget, id: localId }}
104
+ onChange={(updatedValue) => {
105
+ handleLinkChange(updatedValue);
106
+ }}
107
+ onBlur={() => {
108
+ // Save on blur to ensure the value is saved when clicking away
109
+ setAttributes({
110
+ [linkRef]: {
111
+ url: localId ? '' : localUrl ? encodeURI(safeDecodeURI(localUrl)) : '',
112
+ linkTarget: localLinkTarget ? '_blank' : undefined,
113
+ id: localId ? localId : undefined,
114
+ },
115
+ });
116
+ }}
117
+ />
118
+ </div>
119
+ {hasLinkData && (
120
+ <div className="base-js-link-picker__status-wrapper">
121
+ <Tooltip text={statusTooltip}>
122
+ <div
123
+ className="base-js-link-picker__status"
124
+ tabIndex={0}
125
+ aria-label={statusTooltip}
126
+ >
127
+ <Icon icon={isInternalPost ? update : external} size={18} />
128
+ <span>{statusLabel}</span>
129
+ </div>
130
+ </Tooltip>
131
+ </div>
132
+ )}
133
+ </div>
64
134
  );
65
135
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "base-js-sw",
3
- "version": "1.0.8",
3
+ "version": "1.0.10",
4
4
  "description": "Reusable Gutenberg block components for WordPress projects",
5
5
  "main": "index.js",
6
6
  "author": "Shape Works",