base-js-sw 1.0.9 → 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.
- package/components/LinkPicker.js +93 -23
- package/package.json +1 -1
package/components/LinkPicker.js
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
30
|
-
const
|
|
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 (
|
|
84
|
+
if (isPostSelection) {
|
|
34
85
|
// Internal post, use ID
|
|
35
86
|
setLocalId(id);
|
|
36
|
-
setLocalUrl(
|
|
87
|
+
setLocalUrl(nextUrl);
|
|
37
88
|
} else {
|
|
38
89
|
// External or anchor link, use URL
|
|
39
|
-
setLocalUrl(
|
|
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
|
-
<
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
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
|
};
|