@contentful/field-editor-rich-text 3.15.2 → 3.16.0
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/dist/cjs/plugins/Hyperlink/components/EntityHyperlink.js +22 -22
- package/dist/cjs/plugins/Hyperlink/components/LinkPopover.js +118 -0
- package/dist/cjs/plugins/Hyperlink/components/ResourceHyperlink.js +23 -23
- package/dist/cjs/plugins/Hyperlink/components/UrlHyperlink.js +21 -25
- package/dist/cjs/plugins/Hyperlink/components/linkHandlers.js +41 -0
- package/dist/cjs/plugins/Hyperlink/components/styles.js +15 -0
- package/dist/esm/plugins/Hyperlink/components/EntityHyperlink.js +23 -23
- package/dist/esm/plugins/Hyperlink/components/LinkPopover.js +67 -0
- package/dist/esm/plugins/Hyperlink/components/ResourceHyperlink.js +24 -24
- package/dist/esm/plugins/Hyperlink/components/UrlHyperlink.js +22 -26
- package/dist/esm/plugins/Hyperlink/components/linkHandlers.js +20 -0
- package/dist/esm/plugins/Hyperlink/components/styles.js +15 -0
- package/dist/types/plugins/Hyperlink/components/LinkPopover.d.ts +11 -0
- package/dist/types/plugins/Hyperlink/components/linkHandlers.d.ts +5 -0
- package/dist/types/plugins/Hyperlink/components/styles.d.ts +3 -0
- package/package.json +2 -2
|
@@ -11,11 +11,12 @@ Object.defineProperty(exports, "EntityHyperlink", {
|
|
|
11
11
|
const _react = /*#__PURE__*/ _interop_require_wildcard(require("react"));
|
|
12
12
|
const _f36components = require("@contentful/f36-components");
|
|
13
13
|
const _ContentfulEditorProvider = require("../../../ContentfulEditorProvider");
|
|
14
|
-
const
|
|
14
|
+
const _queries = require("../../../internal/queries");
|
|
15
15
|
const _SdkProvider = require("../../../SdkProvider");
|
|
16
16
|
const _linkstracking = require("../../links-tracking");
|
|
17
|
-
const _HyperlinkModal = require("../HyperlinkModal");
|
|
18
17
|
const _useEntityInfo = require("../useEntityInfo");
|
|
18
|
+
const _linkHandlers = require("./linkHandlers");
|
|
19
|
+
const _LinkPopover = require("./LinkPopover");
|
|
19
20
|
const _styles = require("./styles");
|
|
20
21
|
function _getRequireWildcardCache(nodeInterop) {
|
|
21
22
|
if (typeof WeakMap !== "function") return null;
|
|
@@ -61,34 +62,33 @@ function _interop_require_wildcard(obj, nodeInterop) {
|
|
|
61
62
|
function EntityHyperlink(props) {
|
|
62
63
|
const editor = (0, _ContentfulEditorProvider.useContentfulEditor)();
|
|
63
64
|
const sdk = (0, _SdkProvider.useSdkContext)();
|
|
65
|
+
const focus = editor.selection?.focus;
|
|
64
66
|
const { target } = props.element.data;
|
|
65
67
|
const { onEntityFetchComplete } = (0, _linkstracking.useLinkTracking)();
|
|
68
|
+
const pathToElement = (0, _queries.findNodePath)(editor, props.element);
|
|
69
|
+
const isLinkFocused = pathToElement && focus && (0, _queries.isChildPath)(focus.path, pathToElement);
|
|
66
70
|
const tooltipContent = (0, _useEntityInfo.useEntityInfo)({
|
|
67
71
|
target,
|
|
68
72
|
sdk,
|
|
69
73
|
onEntityFetchComplete
|
|
70
74
|
});
|
|
71
|
-
if (!target)
|
|
72
|
-
|
|
73
|
-
event.preventDefault();
|
|
74
|
-
event.stopPropagation();
|
|
75
|
-
if (!editor) return;
|
|
76
|
-
const p = (0, _internal.fromDOMPoint)(editor, [
|
|
77
|
-
event.target,
|
|
78
|
-
0
|
|
79
|
-
]);
|
|
80
|
-
if (p) {
|
|
81
|
-
(0, _HyperlinkModal.addOrEditLink)(editor, sdk, editor.tracking.onViewportAction, p.path);
|
|
82
|
-
}
|
|
75
|
+
if (!target) {
|
|
76
|
+
return null;
|
|
83
77
|
}
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
78
|
+
const popoverText = /*#__PURE__*/ _react.createElement(_f36components.Text, {
|
|
79
|
+
fontColor: "blue600",
|
|
80
|
+
fontWeight: "fontWeightMedium",
|
|
81
|
+
className: _styles.styles.openLink
|
|
82
|
+
}, tooltipContent);
|
|
83
|
+
return /*#__PURE__*/ _react.createElement(_LinkPopover.LinkPopover, {
|
|
84
|
+
isLinkFocused: isLinkFocused,
|
|
85
|
+
handleEditLink: ()=>(0, _linkHandlers.handleEditLink)(editor, sdk, pathToElement),
|
|
86
|
+
handleRemoveLink: ()=>(0, _linkHandlers.handleRemoveLink)(editor),
|
|
87
|
+
popoverText: popoverText
|
|
88
|
+
}, /*#__PURE__*/ _react.createElement(_f36components.Text, {
|
|
89
|
+
testId: "cf-ui-text-link",
|
|
90
|
+
fontColor: "blue600",
|
|
91
|
+
fontWeight: "fontWeightMedium",
|
|
92
92
|
className: _styles.styles.hyperlink,
|
|
93
93
|
"data-link-type": target.sys.linkType,
|
|
94
94
|
"data-link-id": target.sys.id
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
Object.defineProperty(exports, "LinkPopover", {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: function() {
|
|
8
|
+
return LinkPopover;
|
|
9
|
+
}
|
|
10
|
+
});
|
|
11
|
+
const _react = /*#__PURE__*/ _interop_require_wildcard(require("react"));
|
|
12
|
+
const _f36components = require("@contentful/f36-components");
|
|
13
|
+
const _f36icons = require("@contentful/f36-icons");
|
|
14
|
+
const _styles = require("./styles");
|
|
15
|
+
function _getRequireWildcardCache(nodeInterop) {
|
|
16
|
+
if (typeof WeakMap !== "function") return null;
|
|
17
|
+
var cacheBabelInterop = new WeakMap();
|
|
18
|
+
var cacheNodeInterop = new WeakMap();
|
|
19
|
+
return (_getRequireWildcardCache = function(nodeInterop) {
|
|
20
|
+
return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
|
|
21
|
+
})(nodeInterop);
|
|
22
|
+
}
|
|
23
|
+
function _interop_require_wildcard(obj, nodeInterop) {
|
|
24
|
+
if (!nodeInterop && obj && obj.__esModule) {
|
|
25
|
+
return obj;
|
|
26
|
+
}
|
|
27
|
+
if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
|
|
28
|
+
return {
|
|
29
|
+
default: obj
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
var cache = _getRequireWildcardCache(nodeInterop);
|
|
33
|
+
if (cache && cache.has(obj)) {
|
|
34
|
+
return cache.get(obj);
|
|
35
|
+
}
|
|
36
|
+
var newObj = {
|
|
37
|
+
__proto__: null
|
|
38
|
+
};
|
|
39
|
+
var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
|
|
40
|
+
for(var key in obj){
|
|
41
|
+
if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
|
|
42
|
+
var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
|
|
43
|
+
if (desc && (desc.get || desc.set)) {
|
|
44
|
+
Object.defineProperty(newObj, key, desc);
|
|
45
|
+
} else {
|
|
46
|
+
newObj[key] = obj[key];
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
newObj.default = obj;
|
|
51
|
+
if (cache) {
|
|
52
|
+
cache.set(obj, newObj);
|
|
53
|
+
}
|
|
54
|
+
return newObj;
|
|
55
|
+
}
|
|
56
|
+
const LinkPopover = ({ isLinkFocused, popoverText, handleEditLink, handleRemoveLink, children, handleCopyLink })=>// eslint-disable-next-line jsx-a11y/no-autofocus -- we don't want to autofocus the popover
|
|
57
|
+
/*#__PURE__*/ _react.createElement(_f36components.Popover, {
|
|
58
|
+
renderOnlyWhenOpen: false,
|
|
59
|
+
usePortal: false,
|
|
60
|
+
autoFocus: false,
|
|
61
|
+
isOpen: isLinkFocused
|
|
62
|
+
}, /*#__PURE__*/ _react.createElement(_f36components.Popover.Trigger, null, children), /*#__PURE__*/ _react.createElement(_f36components.Popover.Content, {
|
|
63
|
+
className: _styles.styles.popover
|
|
64
|
+
}, /*#__PURE__*/ _react.createElement(_f36components.Flex, {
|
|
65
|
+
contentEditable: "false",
|
|
66
|
+
alignItems: "center",
|
|
67
|
+
paddingTop: "spacing2Xs",
|
|
68
|
+
paddingBottom: "spacing2Xs",
|
|
69
|
+
paddingRight: "spacing2Xs",
|
|
70
|
+
paddingLeft: "spacingXs"
|
|
71
|
+
}, popoverText, handleCopyLink && /*#__PURE__*/ _react.createElement(_f36components.Tooltip, {
|
|
72
|
+
placement: "bottom",
|
|
73
|
+
content: "Copy link",
|
|
74
|
+
usePortal: true
|
|
75
|
+
}, /*#__PURE__*/ _react.createElement(_f36components.IconButton, {
|
|
76
|
+
className: _styles.styles.iconButton,
|
|
77
|
+
onClick: handleCopyLink,
|
|
78
|
+
size: "small",
|
|
79
|
+
variant: "transparent",
|
|
80
|
+
"aria-label": "Copy link",
|
|
81
|
+
icon: /*#__PURE__*/ _react.createElement(_f36icons.CopyIcon, {
|
|
82
|
+
size: "tiny"
|
|
83
|
+
})
|
|
84
|
+
})), /*#__PURE__*/ _react.createElement(_f36components.Tooltip, {
|
|
85
|
+
placement: "bottom",
|
|
86
|
+
content: "Edit link",
|
|
87
|
+
usePortal: true
|
|
88
|
+
}, /*#__PURE__*/ _react.createElement(_f36components.IconButton, {
|
|
89
|
+
className: _styles.styles.iconButton,
|
|
90
|
+
onClick: handleEditLink,
|
|
91
|
+
size: "small",
|
|
92
|
+
variant: "transparent",
|
|
93
|
+
"aria-label": "Edit link",
|
|
94
|
+
icon: /*#__PURE__*/ _react.createElement(_f36icons.EditIcon, {
|
|
95
|
+
size: "tiny"
|
|
96
|
+
})
|
|
97
|
+
})), /*#__PURE__*/ _react.createElement(_f36components.Tooltip, {
|
|
98
|
+
placement: "bottom",
|
|
99
|
+
content: "Remove link",
|
|
100
|
+
usePortal: true
|
|
101
|
+
}, /*#__PURE__*/ _react.createElement(_f36components.IconButton, {
|
|
102
|
+
onClick: handleRemoveLink,
|
|
103
|
+
className: _styles.styles.iconButton,
|
|
104
|
+
size: "small",
|
|
105
|
+
variant: "transparent",
|
|
106
|
+
"aria-label": "Remove link",
|
|
107
|
+
icon: //@TODO: Replace icon when available in f36
|
|
108
|
+
/*#__PURE__*/ _react.createElement("svg", {
|
|
109
|
+
width: "16",
|
|
110
|
+
height: "16",
|
|
111
|
+
viewBox: "0 0 16 16",
|
|
112
|
+
fill: "none",
|
|
113
|
+
xmlns: "http://www.w3.org/2000/svg"
|
|
114
|
+
}, /*#__PURE__*/ _react.createElement("path", {
|
|
115
|
+
d: "M1.75 8C1.75 8.59674 1.98705 9.16903 2.40901 9.59099C2.83097 10.0129 3.40326 10.25 4 10.25H6.5C6.69891 10.25 6.88968 10.329 7.03033 10.4697C7.17098 10.6103 7.25 10.8011 7.25 11C7.25 11.1989 7.17098 11.3897 7.03033 11.5303C6.88968 11.671 6.69891 11.75 6.5 11.75H4C3.00544 11.75 2.05161 11.3549 1.34835 10.6517C0.645088 9.94839 0.25 8.99456 0.25 8C0.25 7.00544 0.645088 6.05161 1.34835 5.34835C2.05161 4.64509 3.00544 4.25 4 4.25H6.5C6.69891 4.25 6.88968 4.32902 7.03033 4.46967C7.17098 4.61032 7.25 4.80109 7.25 5C7.25 5.19891 7.17098 5.38968 7.03033 5.53033C6.88968 5.67098 6.69891 5.75 6.5 5.75H4C3.40326 5.75 2.83097 5.98705 2.40901 6.40901C1.98705 6.83097 1.75 7.40326 1.75 8ZM12 4.25H9.5C9.30109 4.25 9.11032 4.32902 8.96967 4.46967C8.82902 4.61032 8.75 4.80109 8.75 5C8.75 5.19891 8.82902 5.38968 8.96967 5.53033C9.11032 5.67098 9.30109 5.75 9.5 5.75H12C12.5967 5.75 13.169 5.98705 13.591 6.40901C14.0129 6.83097 14.25 7.40326 14.25 8C14.25 8.59674 14.0129 9.16903 13.591 9.59099C13.169 10.0129 12.5967 10.25 12 10.25H9.5C9.30109 10.25 9.11032 10.329 8.96967 10.4697C8.82902 10.6103 8.75 10.8011 8.75 11C8.75 11.1989 8.82902 11.3897 8.96967 11.5303C9.11032 11.671 9.30109 11.75 9.5 11.75H12C12.9946 11.75 13.9484 11.3549 14.6517 10.6517C15.3549 9.94839 15.75 8.99456 15.75 8C15.75 7.00544 15.3549 6.05161 14.6517 5.34835C13.9484 4.64509 12.9946 4.25 12 4.25Z",
|
|
116
|
+
fill: "black"
|
|
117
|
+
}))
|
|
118
|
+
})))));
|
|
@@ -11,11 +11,12 @@ Object.defineProperty(exports, "ResourceHyperlink", {
|
|
|
11
11
|
const _react = /*#__PURE__*/ _interop_require_wildcard(require("react"));
|
|
12
12
|
const _f36components = require("@contentful/f36-components");
|
|
13
13
|
const _ContentfulEditorProvider = require("../../../ContentfulEditorProvider");
|
|
14
|
-
const
|
|
15
|
-
const _linkstracking = require("../../../plugins/links-tracking");
|
|
14
|
+
const _queries = require("../../../internal/queries");
|
|
16
15
|
const _SdkProvider = require("../../../SdkProvider");
|
|
17
|
-
const
|
|
16
|
+
const _linkstracking = require("../../links-tracking");
|
|
18
17
|
const _useResourceEntityInfo = require("../useResourceEntityInfo");
|
|
18
|
+
const _linkHandlers = require("./linkHandlers");
|
|
19
|
+
const _LinkPopover = require("./LinkPopover");
|
|
19
20
|
const _styles = require("./styles");
|
|
20
21
|
function _getRequireWildcardCache(nodeInterop) {
|
|
21
22
|
if (typeof WeakMap !== "function") return null;
|
|
@@ -61,33 +62,32 @@ function _interop_require_wildcard(obj, nodeInterop) {
|
|
|
61
62
|
function ResourceHyperlink(props) {
|
|
62
63
|
const editor = (0, _ContentfulEditorProvider.useContentfulEditor)();
|
|
63
64
|
const sdk = (0, _SdkProvider.useSdkContext)();
|
|
65
|
+
const focus = editor.selection?.focus;
|
|
64
66
|
const { target } = props.element.data;
|
|
65
67
|
const { onEntityFetchComplete } = (0, _linkstracking.useLinkTracking)();
|
|
68
|
+
const pathToElement = (0, _queries.findNodePath)(editor, props.element);
|
|
69
|
+
const isLinkFocused = pathToElement && focus && (0, _queries.isChildPath)(focus.path, pathToElement);
|
|
66
70
|
const tooltipContent = (0, _useResourceEntityInfo.useResourceEntityInfo)({
|
|
67
71
|
target,
|
|
68
72
|
onEntityFetchComplete
|
|
69
73
|
});
|
|
70
|
-
if (!target)
|
|
71
|
-
|
|
72
|
-
event.preventDefault();
|
|
73
|
-
event.stopPropagation();
|
|
74
|
-
if (!editor) return;
|
|
75
|
-
const p = (0, _internal.fromDOMPoint)(editor, [
|
|
76
|
-
event.target,
|
|
77
|
-
0
|
|
78
|
-
]);
|
|
79
|
-
if (p) {
|
|
80
|
-
(0, _HyperlinkModal.addOrEditLink)(editor, sdk, editor.tracking.onViewportAction, p.path);
|
|
81
|
-
}
|
|
74
|
+
if (!target) {
|
|
75
|
+
return null;
|
|
82
76
|
}
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
77
|
+
const popoverText = /*#__PURE__*/ _react.createElement(_f36components.Text, {
|
|
78
|
+
fontColor: "blue600",
|
|
79
|
+
fontWeight: "fontWeightMedium",
|
|
80
|
+
className: _styles.styles.openLink
|
|
81
|
+
}, tooltipContent);
|
|
82
|
+
return /*#__PURE__*/ _react.createElement(_LinkPopover.LinkPopover, {
|
|
83
|
+
isLinkFocused: isLinkFocused,
|
|
84
|
+
handleEditLink: ()=>(0, _linkHandlers.handleEditLink)(editor, sdk, pathToElement),
|
|
85
|
+
handleRemoveLink: ()=>(0, _linkHandlers.handleRemoveLink)(editor),
|
|
86
|
+
popoverText: popoverText
|
|
87
|
+
}, /*#__PURE__*/ _react.createElement(_f36components.Text, {
|
|
88
|
+
testId: "cf-ui-text-link",
|
|
89
|
+
fontColor: "blue600",
|
|
90
|
+
fontWeight: "fontWeightMedium",
|
|
91
91
|
className: _styles.styles.hyperlink,
|
|
92
92
|
"data-resource-link-type": target.sys.linkType,
|
|
93
93
|
"data-resource-link-urn": target.sys.urn
|
|
@@ -11,9 +11,10 @@ Object.defineProperty(exports, "UrlHyperlink", {
|
|
|
11
11
|
const _react = /*#__PURE__*/ _interop_require_wildcard(require("react"));
|
|
12
12
|
const _f36components = require("@contentful/f36-components");
|
|
13
13
|
const _ContentfulEditorProvider = require("../../../ContentfulEditorProvider");
|
|
14
|
-
const
|
|
14
|
+
const _queries = require("../../../internal/queries");
|
|
15
15
|
const _SdkProvider = require("../../../SdkProvider");
|
|
16
|
-
const
|
|
16
|
+
const _linkHandlers = require("./linkHandlers");
|
|
17
|
+
const _LinkPopover = require("./LinkPopover");
|
|
17
18
|
const _styles = require("./styles");
|
|
18
19
|
function _getRequireWildcardCache(nodeInterop) {
|
|
19
20
|
if (typeof WeakMap !== "function") return null;
|
|
@@ -59,31 +60,26 @@ function _interop_require_wildcard(obj, nodeInterop) {
|
|
|
59
60
|
function UrlHyperlink(props) {
|
|
60
61
|
const editor = (0, _ContentfulEditorProvider.useContentfulEditor)();
|
|
61
62
|
const sdk = (0, _SdkProvider.useSdkContext)();
|
|
62
|
-
const
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
event.target,
|
|
69
|
-
0
|
|
70
|
-
], {
|
|
71
|
-
exactMatch: false,
|
|
72
|
-
suppressThrow: false
|
|
73
|
-
});
|
|
74
|
-
(0, _HyperlinkModal.addOrEditLink)(editor, sdk, editor.tracking.onViewportAction, p?.path);
|
|
75
|
-
}
|
|
76
|
-
return /*#__PURE__*/ _react.createElement(_f36components.Tooltip, {
|
|
77
|
-
usePortal: true,
|
|
78
|
-
content: uri,
|
|
79
|
-
targetWrapperClassName: _styles.styles.hyperlinkWrapper,
|
|
80
|
-
placement: "bottom",
|
|
81
|
-
maxWidth: "min-content"
|
|
82
|
-
}, /*#__PURE__*/ _react.createElement(_f36components.TextLink, {
|
|
83
|
-
as: "a",
|
|
63
|
+
const focus = editor.selection?.focus;
|
|
64
|
+
const uri = props.element.data?.uri;
|
|
65
|
+
const pathToElement = (0, _queries.findNodePath)(editor, props.element);
|
|
66
|
+
const isLinkFocused = pathToElement && focus && (0, _queries.isChildPath)(focus.path, pathToElement);
|
|
67
|
+
const popoverText = /*#__PURE__*/ _react.createElement(_f36components.TextLink, {
|
|
68
|
+
className: _styles.styles.openLink,
|
|
84
69
|
href: uri,
|
|
85
70
|
rel: "noopener noreferrer",
|
|
86
|
-
|
|
71
|
+
target: "_blank"
|
|
72
|
+
}, uri);
|
|
73
|
+
return /*#__PURE__*/ _react.createElement(_LinkPopover.LinkPopover, {
|
|
74
|
+
isLinkFocused: isLinkFocused,
|
|
75
|
+
handleEditLink: ()=>(0, _linkHandlers.handleEditLink)(editor, sdk, pathToElement),
|
|
76
|
+
handleRemoveLink: ()=>(0, _linkHandlers.handleRemoveLink)(editor),
|
|
77
|
+
handleCopyLink: ()=>(0, _linkHandlers.handleCopyLink)(uri),
|
|
78
|
+
popoverText: popoverText
|
|
79
|
+
}, /*#__PURE__*/ _react.createElement(_f36components.Text, {
|
|
80
|
+
testId: "cf-ui-text-link",
|
|
81
|
+
fontColor: "blue600",
|
|
82
|
+
fontWeight: "fontWeightMedium",
|
|
87
83
|
className: _styles.styles.hyperlink
|
|
88
84
|
}, props.children));
|
|
89
85
|
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
function _export(target, all) {
|
|
6
|
+
for(var name in all)Object.defineProperty(target, name, {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: all[name]
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
_export(exports, {
|
|
12
|
+
handleCopyLink: function() {
|
|
13
|
+
return handleCopyLink;
|
|
14
|
+
},
|
|
15
|
+
handleEditLink: function() {
|
|
16
|
+
return handleEditLink;
|
|
17
|
+
},
|
|
18
|
+
handleRemoveLink: function() {
|
|
19
|
+
return handleRemoveLink;
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
const _f36components = require("@contentful/f36-components");
|
|
23
|
+
const _editor = require("../../../helpers/editor");
|
|
24
|
+
const _HyperlinkModal = require("../HyperlinkModal");
|
|
25
|
+
const handleEditLink = (editor, sdk, pathToElement)=>{
|
|
26
|
+
if (!editor || !pathToElement) return;
|
|
27
|
+
(0, _HyperlinkModal.addOrEditLink)(editor, sdk, editor.tracking.onViewportAction, pathToElement);
|
|
28
|
+
};
|
|
29
|
+
const handleRemoveLink = (editor)=>{
|
|
30
|
+
(0, _editor.unwrapLink)(editor);
|
|
31
|
+
};
|
|
32
|
+
const handleCopyLink = async (uri)=>{
|
|
33
|
+
if (uri) {
|
|
34
|
+
try {
|
|
35
|
+
await navigator.clipboard.writeText(uri);
|
|
36
|
+
_f36components.Notification.success('Successfully copied URL to clipboard');
|
|
37
|
+
} catch (error) {
|
|
38
|
+
_f36components.Notification.error('Failed to copy URL to clipboard');
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
};
|
|
@@ -23,6 +23,21 @@ const styles = {
|
|
|
23
23
|
fontSize: 'inherit !important'
|
|
24
24
|
}
|
|
25
25
|
}),
|
|
26
|
+
iconButton: (0, _emotion.css)({
|
|
27
|
+
padding: `${_f36tokens.default.spacing2Xs} ${_f36tokens.default.spacingXs}`
|
|
28
|
+
}),
|
|
29
|
+
openLink: (0, _emotion.css)({
|
|
30
|
+
display: 'inline-block',
|
|
31
|
+
marginLeft: _f36tokens.default.spacingXs,
|
|
32
|
+
marginRight: _f36tokens.default.spacingXs,
|
|
33
|
+
maxWidth: '22ch',
|
|
34
|
+
whiteSpace: 'nowrap',
|
|
35
|
+
overflow: 'hidden',
|
|
36
|
+
textOverflow: 'ellipsis'
|
|
37
|
+
}),
|
|
38
|
+
popover: (0, _emotion.css)({
|
|
39
|
+
zIndex: _f36tokens.default.zIndexDefault
|
|
40
|
+
}),
|
|
26
41
|
hyperlink: (0, _emotion.css)({
|
|
27
42
|
fontSize: 'inherit !important',
|
|
28
43
|
display: 'inline !important',
|
|
@@ -1,43 +1,43 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import { Text } from '@contentful/f36-components';
|
|
3
3
|
import { useContentfulEditor } from '../../../ContentfulEditorProvider';
|
|
4
|
-
import {
|
|
4
|
+
import { findNodePath, isChildPath } from '../../../internal/queries';
|
|
5
5
|
import { useSdkContext } from '../../../SdkProvider';
|
|
6
6
|
import { useLinkTracking } from '../../links-tracking';
|
|
7
|
-
import { addOrEditLink } from '../HyperlinkModal';
|
|
8
7
|
import { useEntityInfo } from '../useEntityInfo';
|
|
8
|
+
import { handleEditLink, handleRemoveLink } from './linkHandlers';
|
|
9
|
+
import { LinkPopover } from './LinkPopover';
|
|
9
10
|
import { styles } from './styles';
|
|
10
11
|
export function EntityHyperlink(props) {
|
|
11
12
|
const editor = useContentfulEditor();
|
|
12
13
|
const sdk = useSdkContext();
|
|
14
|
+
const focus = editor.selection?.focus;
|
|
13
15
|
const { target } = props.element.data;
|
|
14
16
|
const { onEntityFetchComplete } = useLinkTracking();
|
|
17
|
+
const pathToElement = findNodePath(editor, props.element);
|
|
18
|
+
const isLinkFocused = pathToElement && focus && isChildPath(focus.path, pathToElement);
|
|
15
19
|
const tooltipContent = useEntityInfo({
|
|
16
20
|
target,
|
|
17
21
|
sdk,
|
|
18
22
|
onEntityFetchComplete
|
|
19
23
|
});
|
|
20
|
-
if (!target)
|
|
21
|
-
|
|
22
|
-
event.preventDefault();
|
|
23
|
-
event.stopPropagation();
|
|
24
|
-
if (!editor) return;
|
|
25
|
-
const p = fromDOMPoint(editor, [
|
|
26
|
-
event.target,
|
|
27
|
-
0
|
|
28
|
-
]);
|
|
29
|
-
if (p) {
|
|
30
|
-
addOrEditLink(editor, sdk, editor.tracking.onViewportAction, p.path);
|
|
31
|
-
}
|
|
24
|
+
if (!target) {
|
|
25
|
+
return null;
|
|
32
26
|
}
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
27
|
+
const popoverText = /*#__PURE__*/ React.createElement(Text, {
|
|
28
|
+
fontColor: "blue600",
|
|
29
|
+
fontWeight: "fontWeightMedium",
|
|
30
|
+
className: styles.openLink
|
|
31
|
+
}, tooltipContent);
|
|
32
|
+
return /*#__PURE__*/ React.createElement(LinkPopover, {
|
|
33
|
+
isLinkFocused: isLinkFocused,
|
|
34
|
+
handleEditLink: ()=>handleEditLink(editor, sdk, pathToElement),
|
|
35
|
+
handleRemoveLink: ()=>handleRemoveLink(editor),
|
|
36
|
+
popoverText: popoverText
|
|
37
|
+
}, /*#__PURE__*/ React.createElement(Text, {
|
|
38
|
+
testId: "cf-ui-text-link",
|
|
39
|
+
fontColor: "blue600",
|
|
40
|
+
fontWeight: "fontWeightMedium",
|
|
41
41
|
className: styles.hyperlink,
|
|
42
42
|
"data-link-type": target.sys.linkType,
|
|
43
43
|
"data-link-id": target.sys.id
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { Popover, IconButton, Tooltip, Flex } from '@contentful/f36-components';
|
|
3
|
+
import { EditIcon, CopyIcon } from '@contentful/f36-icons';
|
|
4
|
+
import { styles } from './styles';
|
|
5
|
+
export const LinkPopover = ({ isLinkFocused, popoverText, handleEditLink, handleRemoveLink, children, handleCopyLink })=>// eslint-disable-next-line jsx-a11y/no-autofocus -- we don't want to autofocus the popover
|
|
6
|
+
/*#__PURE__*/ React.createElement(Popover, {
|
|
7
|
+
renderOnlyWhenOpen: false,
|
|
8
|
+
usePortal: false,
|
|
9
|
+
autoFocus: false,
|
|
10
|
+
isOpen: isLinkFocused
|
|
11
|
+
}, /*#__PURE__*/ React.createElement(Popover.Trigger, null, children), /*#__PURE__*/ React.createElement(Popover.Content, {
|
|
12
|
+
className: styles.popover
|
|
13
|
+
}, /*#__PURE__*/ React.createElement(Flex, {
|
|
14
|
+
contentEditable: "false",
|
|
15
|
+
alignItems: "center",
|
|
16
|
+
paddingTop: "spacing2Xs",
|
|
17
|
+
paddingBottom: "spacing2Xs",
|
|
18
|
+
paddingRight: "spacing2Xs",
|
|
19
|
+
paddingLeft: "spacingXs"
|
|
20
|
+
}, popoverText, handleCopyLink && /*#__PURE__*/ React.createElement(Tooltip, {
|
|
21
|
+
placement: "bottom",
|
|
22
|
+
content: "Copy link",
|
|
23
|
+
usePortal: true
|
|
24
|
+
}, /*#__PURE__*/ React.createElement(IconButton, {
|
|
25
|
+
className: styles.iconButton,
|
|
26
|
+
onClick: handleCopyLink,
|
|
27
|
+
size: "small",
|
|
28
|
+
variant: "transparent",
|
|
29
|
+
"aria-label": "Copy link",
|
|
30
|
+
icon: /*#__PURE__*/ React.createElement(CopyIcon, {
|
|
31
|
+
size: "tiny"
|
|
32
|
+
})
|
|
33
|
+
})), /*#__PURE__*/ React.createElement(Tooltip, {
|
|
34
|
+
placement: "bottom",
|
|
35
|
+
content: "Edit link",
|
|
36
|
+
usePortal: true
|
|
37
|
+
}, /*#__PURE__*/ React.createElement(IconButton, {
|
|
38
|
+
className: styles.iconButton,
|
|
39
|
+
onClick: handleEditLink,
|
|
40
|
+
size: "small",
|
|
41
|
+
variant: "transparent",
|
|
42
|
+
"aria-label": "Edit link",
|
|
43
|
+
icon: /*#__PURE__*/ React.createElement(EditIcon, {
|
|
44
|
+
size: "tiny"
|
|
45
|
+
})
|
|
46
|
+
})), /*#__PURE__*/ React.createElement(Tooltip, {
|
|
47
|
+
placement: "bottom",
|
|
48
|
+
content: "Remove link",
|
|
49
|
+
usePortal: true
|
|
50
|
+
}, /*#__PURE__*/ React.createElement(IconButton, {
|
|
51
|
+
onClick: handleRemoveLink,
|
|
52
|
+
className: styles.iconButton,
|
|
53
|
+
size: "small",
|
|
54
|
+
variant: "transparent",
|
|
55
|
+
"aria-label": "Remove link",
|
|
56
|
+
icon: //@TODO: Replace icon when available in f36
|
|
57
|
+
/*#__PURE__*/ React.createElement("svg", {
|
|
58
|
+
width: "16",
|
|
59
|
+
height: "16",
|
|
60
|
+
viewBox: "0 0 16 16",
|
|
61
|
+
fill: "none",
|
|
62
|
+
xmlns: "http://www.w3.org/2000/svg"
|
|
63
|
+
}, /*#__PURE__*/ React.createElement("path", {
|
|
64
|
+
d: "M1.75 8C1.75 8.59674 1.98705 9.16903 2.40901 9.59099C2.83097 10.0129 3.40326 10.25 4 10.25H6.5C6.69891 10.25 6.88968 10.329 7.03033 10.4697C7.17098 10.6103 7.25 10.8011 7.25 11C7.25 11.1989 7.17098 11.3897 7.03033 11.5303C6.88968 11.671 6.69891 11.75 6.5 11.75H4C3.00544 11.75 2.05161 11.3549 1.34835 10.6517C0.645088 9.94839 0.25 8.99456 0.25 8C0.25 7.00544 0.645088 6.05161 1.34835 5.34835C2.05161 4.64509 3.00544 4.25 4 4.25H6.5C6.69891 4.25 6.88968 4.32902 7.03033 4.46967C7.17098 4.61032 7.25 4.80109 7.25 5C7.25 5.19891 7.17098 5.38968 7.03033 5.53033C6.88968 5.67098 6.69891 5.75 6.5 5.75H4C3.40326 5.75 2.83097 5.98705 2.40901 6.40901C1.98705 6.83097 1.75 7.40326 1.75 8ZM12 4.25H9.5C9.30109 4.25 9.11032 4.32902 8.96967 4.46967C8.82902 4.61032 8.75 4.80109 8.75 5C8.75 5.19891 8.82902 5.38968 8.96967 5.53033C9.11032 5.67098 9.30109 5.75 9.5 5.75H12C12.5967 5.75 13.169 5.98705 13.591 6.40901C14.0129 6.83097 14.25 7.40326 14.25 8C14.25 8.59674 14.0129 9.16903 13.591 9.59099C13.169 10.0129 12.5967 10.25 12 10.25H9.5C9.30109 10.25 9.11032 10.329 8.96967 10.4697C8.82902 10.6103 8.75 10.8011 8.75 11C8.75 11.1989 8.82902 11.3897 8.96967 11.5303C9.11032 11.671 9.30109 11.75 9.5 11.75H12C12.9946 11.75 13.9484 11.3549 14.6517 10.6517C15.3549 9.94839 15.75 8.99456 15.75 8C15.75 7.00544 15.3549 6.05161 14.6517 5.34835C13.9484 4.64509 12.9946 4.25 12 4.25Z",
|
|
65
|
+
fill: "black"
|
|
66
|
+
}))
|
|
67
|
+
})))));
|
|
@@ -1,42 +1,42 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import { Text } from '@contentful/f36-components';
|
|
3
3
|
import { useContentfulEditor } from '../../../ContentfulEditorProvider';
|
|
4
|
-
import {
|
|
5
|
-
import { useLinkTracking } from '../../../plugins/links-tracking';
|
|
4
|
+
import { findNodePath, isChildPath } from '../../../internal/queries';
|
|
6
5
|
import { useSdkContext } from '../../../SdkProvider';
|
|
7
|
-
import {
|
|
6
|
+
import { useLinkTracking } from '../../links-tracking';
|
|
8
7
|
import { useResourceEntityInfo } from '../useResourceEntityInfo';
|
|
8
|
+
import { handleEditLink, handleRemoveLink } from './linkHandlers';
|
|
9
|
+
import { LinkPopover } from './LinkPopover';
|
|
9
10
|
import { styles } from './styles';
|
|
10
11
|
export function ResourceHyperlink(props) {
|
|
11
12
|
const editor = useContentfulEditor();
|
|
12
13
|
const sdk = useSdkContext();
|
|
14
|
+
const focus = editor.selection?.focus;
|
|
13
15
|
const { target } = props.element.data;
|
|
14
16
|
const { onEntityFetchComplete } = useLinkTracking();
|
|
17
|
+
const pathToElement = findNodePath(editor, props.element);
|
|
18
|
+
const isLinkFocused = pathToElement && focus && isChildPath(focus.path, pathToElement);
|
|
15
19
|
const tooltipContent = useResourceEntityInfo({
|
|
16
20
|
target,
|
|
17
21
|
onEntityFetchComplete
|
|
18
22
|
});
|
|
19
|
-
if (!target)
|
|
20
|
-
|
|
21
|
-
event.preventDefault();
|
|
22
|
-
event.stopPropagation();
|
|
23
|
-
if (!editor) return;
|
|
24
|
-
const p = fromDOMPoint(editor, [
|
|
25
|
-
event.target,
|
|
26
|
-
0
|
|
27
|
-
]);
|
|
28
|
-
if (p) {
|
|
29
|
-
addOrEditLink(editor, sdk, editor.tracking.onViewportAction, p.path);
|
|
30
|
-
}
|
|
23
|
+
if (!target) {
|
|
24
|
+
return null;
|
|
31
25
|
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
26
|
+
const popoverText = /*#__PURE__*/ React.createElement(Text, {
|
|
27
|
+
fontColor: "blue600",
|
|
28
|
+
fontWeight: "fontWeightMedium",
|
|
29
|
+
className: styles.openLink
|
|
30
|
+
}, tooltipContent);
|
|
31
|
+
return /*#__PURE__*/ React.createElement(LinkPopover, {
|
|
32
|
+
isLinkFocused: isLinkFocused,
|
|
33
|
+
handleEditLink: ()=>handleEditLink(editor, sdk, pathToElement),
|
|
34
|
+
handleRemoveLink: ()=>handleRemoveLink(editor),
|
|
35
|
+
popoverText: popoverText
|
|
36
|
+
}, /*#__PURE__*/ React.createElement(Text, {
|
|
37
|
+
testId: "cf-ui-text-link",
|
|
38
|
+
fontColor: "blue600",
|
|
39
|
+
fontWeight: "fontWeightMedium",
|
|
40
40
|
className: styles.hyperlink,
|
|
41
41
|
"data-resource-link-type": target.sys.linkType,
|
|
42
42
|
"data-resource-link-urn": target.sys.urn
|
|
@@ -1,38 +1,34 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import { TextLink, Text } from '@contentful/f36-components';
|
|
3
3
|
import { useContentfulEditor } from '../../../ContentfulEditorProvider';
|
|
4
|
-
import {
|
|
4
|
+
import { findNodePath, isChildPath } from '../../../internal/queries';
|
|
5
5
|
import { useSdkContext } from '../../../SdkProvider';
|
|
6
|
-
import {
|
|
6
|
+
import { handleCopyLink, handleEditLink, handleRemoveLink } from './linkHandlers';
|
|
7
|
+
import { LinkPopover } from './LinkPopover';
|
|
7
8
|
import { styles } from './styles';
|
|
8
9
|
export function UrlHyperlink(props) {
|
|
9
10
|
const editor = useContentfulEditor();
|
|
10
11
|
const sdk = useSdkContext();
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
event.target,
|
|
18
|
-
0
|
|
19
|
-
], {
|
|
20
|
-
exactMatch: false,
|
|
21
|
-
suppressThrow: false
|
|
22
|
-
});
|
|
23
|
-
addOrEditLink(editor, sdk, editor.tracking.onViewportAction, p?.path);
|
|
24
|
-
}
|
|
25
|
-
return /*#__PURE__*/ React.createElement(Tooltip, {
|
|
26
|
-
usePortal: true,
|
|
27
|
-
content: uri,
|
|
28
|
-
targetWrapperClassName: styles.hyperlinkWrapper,
|
|
29
|
-
placement: "bottom",
|
|
30
|
-
maxWidth: "min-content"
|
|
31
|
-
}, /*#__PURE__*/ React.createElement(TextLink, {
|
|
32
|
-
as: "a",
|
|
12
|
+
const focus = editor.selection?.focus;
|
|
13
|
+
const uri = props.element.data?.uri;
|
|
14
|
+
const pathToElement = findNodePath(editor, props.element);
|
|
15
|
+
const isLinkFocused = pathToElement && focus && isChildPath(focus.path, pathToElement);
|
|
16
|
+
const popoverText = /*#__PURE__*/ React.createElement(TextLink, {
|
|
17
|
+
className: styles.openLink,
|
|
33
18
|
href: uri,
|
|
34
19
|
rel: "noopener noreferrer",
|
|
35
|
-
|
|
20
|
+
target: "_blank"
|
|
21
|
+
}, uri);
|
|
22
|
+
return /*#__PURE__*/ React.createElement(LinkPopover, {
|
|
23
|
+
isLinkFocused: isLinkFocused,
|
|
24
|
+
handleEditLink: ()=>handleEditLink(editor, sdk, pathToElement),
|
|
25
|
+
handleRemoveLink: ()=>handleRemoveLink(editor),
|
|
26
|
+
handleCopyLink: ()=>handleCopyLink(uri),
|
|
27
|
+
popoverText: popoverText
|
|
28
|
+
}, /*#__PURE__*/ React.createElement(Text, {
|
|
29
|
+
testId: "cf-ui-text-link",
|
|
30
|
+
fontColor: "blue600",
|
|
31
|
+
fontWeight: "fontWeightMedium",
|
|
36
32
|
className: styles.hyperlink
|
|
37
33
|
}, props.children));
|
|
38
34
|
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Notification } from '@contentful/f36-components';
|
|
2
|
+
import { unwrapLink } from '../../../helpers/editor';
|
|
3
|
+
import { addOrEditLink } from '../HyperlinkModal';
|
|
4
|
+
export const handleEditLink = (editor, sdk, pathToElement)=>{
|
|
5
|
+
if (!editor || !pathToElement) return;
|
|
6
|
+
addOrEditLink(editor, sdk, editor.tracking.onViewportAction, pathToElement);
|
|
7
|
+
};
|
|
8
|
+
export const handleRemoveLink = (editor)=>{
|
|
9
|
+
unwrapLink(editor);
|
|
10
|
+
};
|
|
11
|
+
export const handleCopyLink = async (uri)=>{
|
|
12
|
+
if (uri) {
|
|
13
|
+
try {
|
|
14
|
+
await navigator.clipboard.writeText(uri);
|
|
15
|
+
Notification.success('Successfully copied URL to clipboard');
|
|
16
|
+
} catch (error) {
|
|
17
|
+
Notification.error('Failed to copy URL to clipboard');
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
};
|
|
@@ -8,6 +8,21 @@ export const styles = {
|
|
|
8
8
|
fontSize: 'inherit !important'
|
|
9
9
|
}
|
|
10
10
|
}),
|
|
11
|
+
iconButton: css({
|
|
12
|
+
padding: `${tokens.spacing2Xs} ${tokens.spacingXs}`
|
|
13
|
+
}),
|
|
14
|
+
openLink: css({
|
|
15
|
+
display: 'inline-block',
|
|
16
|
+
marginLeft: tokens.spacingXs,
|
|
17
|
+
marginRight: tokens.spacingXs,
|
|
18
|
+
maxWidth: '22ch',
|
|
19
|
+
whiteSpace: 'nowrap',
|
|
20
|
+
overflow: 'hidden',
|
|
21
|
+
textOverflow: 'ellipsis'
|
|
22
|
+
}),
|
|
23
|
+
popover: css({
|
|
24
|
+
zIndex: tokens.zIndexDefault
|
|
25
|
+
}),
|
|
11
26
|
hyperlink: css({
|
|
12
27
|
fontSize: 'inherit !important',
|
|
13
28
|
display: 'inline !important',
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
type LinkPopoverProps = {
|
|
3
|
+
isLinkFocused: boolean | undefined;
|
|
4
|
+
popoverText: React.ReactNode;
|
|
5
|
+
handleEditLink: () => void;
|
|
6
|
+
handleRemoveLink: () => void;
|
|
7
|
+
children: React.ReactNode;
|
|
8
|
+
handleCopyLink?: () => void;
|
|
9
|
+
};
|
|
10
|
+
export declare const LinkPopover: ({ isLinkFocused, popoverText, handleEditLink, handleRemoveLink, children, handleCopyLink, }: LinkPopoverProps) => React.JSX.Element;
|
|
11
|
+
export {};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { FieldAppSDK } from '@contentful/app-sdk';
|
|
2
|
+
import { Path, PlateEditor } from '../../../internal/types';
|
|
3
|
+
export declare const handleEditLink: (editor: PlateEditor, sdk: FieldAppSDK, pathToElement: Path | undefined) => void;
|
|
4
|
+
export declare const handleRemoveLink: (editor: PlateEditor) => void;
|
|
5
|
+
export declare const handleCopyLink: (uri: string | undefined) => Promise<void>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contentful/field-editor-rich-text",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.16.0",
|
|
4
4
|
"source": "./src/index.tsx",
|
|
5
5
|
"main": "dist/cjs/index.js",
|
|
6
6
|
"module": "dist/esm/index.js",
|
|
@@ -81,5 +81,5 @@
|
|
|
81
81
|
"prism-react-renderer": "2.0.5",
|
|
82
82
|
"react": ">=16.14.0"
|
|
83
83
|
},
|
|
84
|
-
"gitHead": "
|
|
84
|
+
"gitHead": "9d07b5cbfb32a72cab6ff4fc4732e236033412bd"
|
|
85
85
|
}
|